Skip to content

Commit 2247c7d

Browse files
committed
JAVA-2815: Add TransientTransactionError error label for reads
1 parent 55c4571 commit 2247c7d

File tree

5 files changed

+146
-15
lines changed

5 files changed

+146
-15
lines changed

driver-async/src/main/com/mongodb/async/client/OperationExecutorImpl.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public void onResult(final ClientSession clientSession, final Throwable t) {
7777
@Override
7878
public void onResult(final T result, final Throwable t) {
7979
try {
80+
labelException(t, session);
8081
errHandlingCallback.onResult(result, t);
8182
} finally {
8283
binding.release();
@@ -111,10 +112,7 @@ public void onResult(final ClientSession clientSession, final Throwable t) {
111112
@Override
112113
public void onResult(final T result, final Throwable t) {
113114
try {
114-
if (t instanceof MongoSocketException && session != null && session.hasActiveTransaction()
115-
&& !((MongoException) t).hasErrorLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
116-
((MongoException) t).addLabel(TRANSIENT_TRANSACTION_ERROR_LABEL);
117-
}
115+
labelException(t, session);
118116
errHandlingCallback.onResult(result, t);
119117
} finally {
120118
binding.release();
@@ -126,6 +124,14 @@ public void onResult(final T result, final Throwable t) {
126124
});
127125
}
128126

127+
128+
private void labelException(final Throwable t, final ClientSession session) {
129+
if (t instanceof MongoSocketException && session != null && session.hasActiveTransaction()
130+
&& !((MongoException) t).hasErrorLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
131+
((MongoException) t).addLabel(TRANSIENT_TRANSACTION_ERROR_LABEL);
132+
}
133+
}
134+
129135
private AsyncReadWriteBinding getReadWriteBinding(final ReadPreference readPreference, final ReadConcern readConcern,
130136
@Nullable final ClientSession session, final boolean ownsSession) {
131137
notNull("readPreference", readPreference);

driver-core/src/test/resources/transactions/README.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ Each YAML file has the following keys:
108108

109109
- ``arguments``: Optional, the names and values of arguments.
110110

111-
- ``result``: The return value from the operation, if any. If the
112-
operation is expected to return an error, the ``result`` has one or more
113-
of the following fields:
111+
- ``result``: The return value from the operation, if any. This field may
112+
be a single document or an array of documents in the case of a
113+
multi-document read. If the operation is expected to return an error, the
114+
``result`` is a single document that has one or more of the following
115+
fields:
114116

115117
- ``errorContains``: A substring of the expected error message.
116118

driver-core/src/test/resources/transactions/error-labels.json

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,14 @@
451451
"failPoint": {
452452
"configureFailPoint": "failCommand",
453453
"mode": {
454-
"times": 1
454+
"times": 4
455455
},
456456
"data": {
457457
"failCommands": [
458-
"insert"
458+
"insert",
459+
"find",
460+
"aggregate",
461+
"distinct"
459462
],
460463
"closeConnection": true
461464
}
@@ -483,6 +486,59 @@
483486
]
484487
}
485488
},
489+
{
490+
"name": "find",
491+
"object": "collection",
492+
"arguments": {
493+
"session": "session0"
494+
},
495+
"result": {
496+
"errorLabelsContain": [
497+
"TransientTransactionError"
498+
],
499+
"errorLabelsOmit": [
500+
"UnknownTransactionCommitResult"
501+
]
502+
}
503+
},
504+
{
505+
"name": "aggregate",
506+
"object": "collection",
507+
"arguments": {
508+
"pipeline": [
509+
{
510+
"$project": {
511+
"_id": 1
512+
}
513+
}
514+
],
515+
"session": "session0"
516+
},
517+
"result": {
518+
"errorLabelsContain": [
519+
"TransientTransactionError"
520+
],
521+
"errorLabelsOmit": [
522+
"UnknownTransactionCommitResult"
523+
]
524+
}
525+
},
526+
{
527+
"name": "distinct",
528+
"object": "collection",
529+
"arguments": {
530+
"fieldName": "_id",
531+
"session": "session0"
532+
},
533+
"result": {
534+
"errorLabelsContain": [
535+
"TransientTransactionError"
536+
],
537+
"errorLabelsOmit": [
538+
"UnknownTransactionCommitResult"
539+
]
540+
}
541+
},
486542
{
487543
"name": "abortTransaction",
488544
"object": "session0"
@@ -512,6 +568,63 @@
512568
"database_name": "transaction-tests"
513569
}
514570
},
571+
{
572+
"command_started_event": {
573+
"command": {
574+
"find": "test",
575+
"readConcern": null,
576+
"lsid": "session0",
577+
"txnNumber": {
578+
"$numberLong": "1"
579+
},
580+
"startTransaction": null,
581+
"autocommit": false
582+
},
583+
"command_name": "find",
584+
"database_name": "transaction-tests"
585+
}
586+
},
587+
{
588+
"command_started_event": {
589+
"command": {
590+
"aggregate": "test",
591+
"pipeline": [
592+
{
593+
"$project": {
594+
"_id": 1
595+
}
596+
}
597+
],
598+
"cursor": {},
599+
"readConcern": null,
600+
"lsid": "session0",
601+
"txnNumber": {
602+
"$numberLong": "1"
603+
},
604+
"startTransaction": null,
605+
"autocommit": false
606+
},
607+
"command_name": "aggregate",
608+
"database_name": "transaction-tests"
609+
}
610+
},
611+
{
612+
"command_started_event": {
613+
"command": {
614+
"distinct": "test",
615+
"key": "_id",
616+
"lsid": "session0",
617+
"readConcern": null,
618+
"txnNumber": {
619+
"$numberLong": "1"
620+
},
621+
"startTransaction": null,
622+
"autocommit": false
623+
},
624+
"command_name": "distinct",
625+
"database_name": "transaction-tests"
626+
}
627+
},
515628
{
516629
"command_started_event": {
517630
"command": {

driver-core/src/test/resources/transactions/reads.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@
100100
}
101101
},
102102
"result": {
103-
"errorContains": "Cannot run 'count' in a multi-document transaction"
103+
"errorContains": "Cannot run 'count' in a multi-document transaction",
104+
"errorLabelsOmit": [
105+
"TransientTransactionError",
106+
"UnknownTransactionCommitResult"
107+
]
104108
}
105109
},
106110
{

driver-sync/src/main/com/mongodb/client/internal/MongoClientDelegate.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ public <T> T execute(final ReadOperation<T> operation, final ReadPreference read
175175
throw new MongoClientException("Read preference in a transaction must be primary");
176176
}
177177
return operation.execute(binding);
178+
} catch (MongoSocketException e) {
179+
labelException(session, e);
180+
throw e;
178181
} finally {
179182
binding.release();
180183
}
@@ -187,12 +190,9 @@ public <T> T execute(final WriteOperation<T> operation, final ReadConcern readCo
187190
try {
188191
return operation.execute(binding);
189192
} catch (MongoSocketException e) {
190-
if (session != null && session.hasActiveTransaction() && !e.hasErrorLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
191-
e.addLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL);
192-
}
193+
labelException(session, e);
193194
throw e;
194-
}
195-
finally {
195+
} finally {
196196
binding.release();
197197
}
198198
}
@@ -216,6 +216,12 @@ ReadWriteBinding getReadWriteBinding(final ReadPreference readPreference, final
216216
return readWriteBinding;
217217
}
218218

219+
private void labelException(final @Nullable ClientSession session, final MongoException e) {
220+
if (session != null && session.hasActiveTransaction() && !e.hasErrorLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
221+
e.addLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL);
222+
}
223+
}
224+
219225
private ReadPreference getReadPreferenceForBinding(final ReadPreference readPreference, @Nullable final ClientSession session) {
220226
if (session == null) {
221227
return readPreference;

0 commit comments

Comments
 (0)