Skip to content

Commit fff1bbd

Browse files
committed
JAVA-2815: Transaction state updates
Change transaction state on first operation after commit from DONE to NONE, and after abort from ABORTED to NONE.
1 parent 24913dc commit fff1bbd

File tree

8 files changed

+443
-33
lines changed

8 files changed

+443
-33
lines changed

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

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@
3232
class ClientSessionImpl extends BaseClientSessionImpl implements ClientSession {
3333

3434
private enum TransactionState {
35-
NONE, IN, DONE, ABORTED
35+
NONE, IN, COMMITTED, ABORTED
3636
}
3737

3838
private final OperationExecutor executor;
3939
private TransactionState transactionState = TransactionState.NONE;
40-
private boolean messageSent;
40+
private boolean messageSentInCurrentTransaction;
4141
private boolean commitInProgress;
4242

4343
private TransactionOptions transactionOptions;
@@ -50,19 +50,26 @@ private enum TransactionState {
5050

5151
@Override
5252
public boolean hasActiveTransaction() {
53-
return transactionState == TransactionState.IN || (transactionState == TransactionState.DONE && commitInProgress);
53+
return transactionState == TransactionState.IN || (transactionState == TransactionState.COMMITTED && commitInProgress);
5454
}
5555

5656
@Override
5757
public boolean notifyMessageSent() {
58-
boolean firstMessage = !messageSent;
59-
messageSent = true;
60-
return firstMessage;
58+
if (hasActiveTransaction()) {
59+
boolean firstMessageInCurrentTransaction = !messageSentInCurrentTransaction;
60+
messageSentInCurrentTransaction = true;
61+
return firstMessageInCurrentTransaction;
62+
} else {
63+
if (transactionState == TransactionState.COMMITTED || transactionState == TransactionState.ABORTED) {
64+
cleanupTransaction(TransactionState.NONE);
65+
}
66+
return false;
67+
}
6168
}
6269

6370
@Override
6471
public TransactionOptions getTransactionOptions() {
65-
isTrue("in transaction", transactionState == TransactionState.IN || transactionState == TransactionState.DONE);
72+
isTrue("in transaction", transactionState == TransactionState.IN || transactionState == TransactionState.COMMITTED);
6673
return transactionOptions;
6774
}
6875

@@ -77,7 +84,7 @@ public void startTransaction(final TransactionOptions transactionOptions) {
7784
if (transactionState == TransactionState.IN) {
7885
throw new IllegalStateException("Transaction already in progress");
7986
}
80-
if (transactionState == TransactionState.DONE) {
87+
if (transactionState == TransactionState.COMMITTED) {
8188
cleanupTransaction(TransactionState.IN);
8289
} else {
8390
transactionState = TransactionState.IN;
@@ -94,8 +101,8 @@ public void commitTransaction(final SingleResultCallback<Void> callback) {
94101
if (transactionState == TransactionState.NONE) {
95102
throw new IllegalStateException("There is no transaction started");
96103
}
97-
if (!messageSent) {
98-
cleanupTransaction(TransactionState.DONE);
104+
if (!messageSentInCurrentTransaction) {
105+
cleanupTransaction(TransactionState.COMMITTED);
99106
callback.onResult(null, null);
100107
} else {
101108
ReadConcern readConcern = transactionOptions.getReadConcern();
@@ -109,7 +116,7 @@ public void commitTransaction(final SingleResultCallback<Void> callback) {
109116
@Override
110117
public void onResult(final Void result, final Throwable t) {
111118
commitInProgress = false;
112-
transactionState = TransactionState.DONE;
119+
transactionState = TransactionState.COMMITTED;
113120
callback.onResult(result, t);
114121
}
115122
});
@@ -121,13 +128,13 @@ public void abortTransaction(final SingleResultCallback<Void> callback) {
121128
if (transactionState == TransactionState.ABORTED) {
122129
throw new IllegalStateException("Cannot call abortTransaction twice");
123130
}
124-
if (transactionState == TransactionState.DONE) {
131+
if (transactionState == TransactionState.COMMITTED) {
125132
throw new IllegalStateException("Cannot call abortTransaction after calling commitTransaction");
126133
}
127134
if (transactionState == TransactionState.NONE) {
128135
throw new IllegalStateException("There is no transaction started");
129136
}
130-
if (!messageSent) {
137+
if (!messageSentInCurrentTransaction) {
131138
cleanupTransaction(TransactionState.ABORTED);
132139
callback.onResult(null, null);
133140
} else {
@@ -163,7 +170,7 @@ public void onResult(final Void result, final Throwable t) {
163170
}
164171

165172
private void cleanupTransaction(final TransactionState nextState) {
166-
messageSent = false;
173+
messageSentInCurrentTransaction = false;
167174
transactionOptions = null;
168175
transactionState = nextState;
169176
}

driver-core/src/main/com/mongodb/internal/connection/CommandMessage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ private List<BsonElement> getExtraElements(final SessionContext sessionContext)
240240
if (sessionContext.hasSession() && responseExpected) {
241241
extraElements.add(new BsonElement("lsid", sessionContext.getSessionId()));
242242
}
243+
boolean firstMessageInTransaction = sessionContext.notifyMessageSent();
243244
if (sessionContext.hasActiveTransaction()) {
244245
extraElements.add(new BsonElement("txnNumber", new BsonInt64(sessionContext.getTransactionNumber())));
245-
boolean firstMessage = sessionContext.notifyMessageSent();
246-
if (firstMessage) {
246+
if (firstMessageInTransaction) {
247247
extraElements.add(new BsonElement("startTransaction", BsonBoolean.TRUE));
248248
addReadConcernDocument(extraElements, sessionContext);
249249
}

driver-core/src/main/com/mongodb/internal/connection/NoOpSessionContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public long advanceTransactionNumber() {
6565

6666
@Override
6767
public boolean notifyMessageSent() {
68-
throw new UnsupportedOperationException();
68+
return false;
6969
}
7070

7171
@Override

driver-core/src/test/functional/com/mongodb/binding/SimpleSessionContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public long advanceTransactionNumber() {
7070

7171
@Override
7272
public boolean notifyMessageSent() {
73-
throw new UnsupportedOperationException();
73+
return false;
7474
}
7575

7676
@Override

0 commit comments

Comments
 (0)