-
Type: Spec Change
-
Resolution: Duplicate
-
Priority: Major - P3
-
None
-
Component/s: Retryability
-
None
-
Not Needed
While testing CDRIVER and PHPC with APM to inspect command documents, I noticed something surprising. If a bulk operation contains a series of single-document operations (e.g. deleteOne, updateOne) followed by a final multi-document operation (e.g. updateMany), only the final command containing the unsupported operation excludes a transaction ID. Based on the language in Unsupported Write Operations, I might expect that one unsupported operation to cause all commands to exclude a transaction ID:
In the context of the CRUD specification, this includes the updateMany() and deleteMany() methods as well as bulkWrite() where the requests parameter includes an UpdateMany or DeleteMany operation. Drivers MUST NOT add a transaction ID to any single- or multi-statement write commands that include one or more multi-document write operations. Drivers MUST NOT retry these commands if they fail to return a response.
This reason for this behavior is that libmongoc checks for a "multi" operation while building individual write command documents (similar to its checks for "collation" option usage), rather than in its bulk write API where delete, insert, and update operations are added.
I've forgotten the thought process that went into the above citation from the retryable writes spec, but I don't see anything technically wrong with what libmongoc is doing. Therefore, I propose rewording the spec to relax the tainting of an entire bulkWrite() based on its requests parameter and instead allow drivers the flexibility to taint individual write commands within a bulkWrite(). This would result in emphasizing the sentence that followed the bolded segment above:
Drivers MUST NOT add a transaction ID to any single- or multi-statement write commands that include one or more multi-document write operations.
I should note that the spec's JSON tests didn't catch this, as they are focused on testing retryable behavior in the face of network errors (i.e. fail point triggers). I ultimately caught this while implementing the Test Plan discussed in the spec document, which says:
If possible, drivers should test that transaction IDs are never included in commands for unsupported write operations:
- Unsupported multi-statement write operations
- bulkWrite() that includes UpdateMany or DeleteMany