While implementing convenient API for transactions spec, I ran into an unhelpful error from the server. The command sent was commitTransaction, and the result was "Transaction X has been aborted", as follows:
W, [2018-12-21T14:41:16.988684 #14570] WARN -- : COMMAND | localhost:27741 | admin.commitTransaction | STARTED | {"commitTransaction"=>1, "$clusterTime"=>{"clusterTime"=>#<BSON::Timestamp:0x00005556c9b31440 @seconds=1545421260, @increment=4>, "signature"=>{"hash"=><BSON::Binary:0x46915619752340 type=generic data=0x0000000000000000...>, "keyId"=>0}}, "txnNumber"=>#<BSON::Int64:0x00005556c985afa0 @integer=2>, "lsid"=>{"id"=><BSON::Binary:0x46915619787740 type=uuid data=0xb2079f3024db4db8...>}, "autocommit"=>false, "writeConcern"=>{"w"=>2}} W, [2018-12-21T14:41:16.989890 #14570] WARN -- : COMMAND | localhost:27741 | admin.commitTransaction | FAILED | Transaction 2 has been aborted. (251) | 0.0011884130000000001s
In other words, the driver requested that a transaction be committed, and the server replied saying transaction was aborted, but did not say why.
Examining the code in the server which returned this string yielded the following:
void Session::_beginOrContinueTxn(WithLock wl, ... if (_txnState == MultiDocumentTransactionState::kInProgress && !_txnResourceStash) { // This indicates that the first command in the transaction failed but did not // implicitly abort the transaction. It is not safe to continue the transaction, in // particular because we have not saved the readConcern from the first statement of // the transaction. _abortTransaction(wl); uasserted(ErrorCodes::NoSuchTransaction, str::stream() << "Transaction " << txnNumber << " has been aborted."); }
In other words, the server chose to abort the transaction when a commit was requested because a prior operation in the transaction failed.
The server should specify that this was the reason for transaction abort in the returned response, for instance the following message would be much more helpful:
Transaction 2 has been aborted because an earlier command in this transaction failed. (251)
Or, perhaps:
Aborting transaction 2 because an earlier command in this transaction failed. (251)
- related to
-
RUBY-1625 POC : Convenient API for Transactions
- Closed