Skip to content

Commit 49b3b92

Browse files
committed
Move documentation example for transactions to the Java repo.
JAVA-3152
1 parent 00dd921 commit 49b3b92

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Copyright 2018 MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package documentation;
19+
20+
import com.mongodb.ConnectionString;
21+
import com.mongodb.MongoClientSettings;
22+
import com.mongodb.client.MongoClient;
23+
import com.mongodb.MongoCommandException;
24+
import com.mongodb.MongoException;
25+
import com.mongodb.ReadConcern;
26+
import com.mongodb.ReadPreference;
27+
import com.mongodb.TransactionOptions;
28+
import com.mongodb.WriteConcern;
29+
import com.mongodb.client.ClientSession;
30+
import com.mongodb.client.MongoClients;
31+
import com.mongodb.client.MongoCollection;
32+
import com.mongodb.client.model.Filters;
33+
import com.mongodb.client.model.Updates;
34+
import org.bson.Document;
35+
import org.junit.After;
36+
import org.junit.Before;
37+
import org.junit.Test;
38+
39+
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet;
40+
import static com.mongodb.ClusterFixture.isSharded;
41+
import static com.mongodb.ClusterFixture.serverVersionAtLeast;
42+
import static com.mongodb.client.Fixture.getMongoClientSettingsBuilder;
43+
import static org.junit.Assume.assumeTrue;
44+
45+
public class TransactionExample {
46+
private MongoClient client;
47+
48+
@Before
49+
public void setUp() {
50+
assumeTrue(canRunTest());
51+
MongoClientSettings.Builder builder = getMongoClientSettingsBuilder()
52+
.applyConnectionString(new ConnectionString(
53+
"mongodb://localhost,localhost:27018,localhost:27019/?serverSelectionTimeoutMS=5000"));
54+
client = MongoClients.create(builder.build());
55+
56+
createCollection(client, "hr", "employees");
57+
createCollection(client, "reporting", "events");
58+
}
59+
60+
@After
61+
public void cleanUp() {
62+
if (client != null) {
63+
client.close();
64+
}
65+
}
66+
67+
@Test
68+
public void updateEmployeeInfoWithRetry() {
69+
runTransactionWithRetry(new Runnable() {
70+
@Override
71+
public void run() {
72+
updateEmployeeInfo();
73+
}
74+
});
75+
}
76+
77+
private void runTransactionWithRetry(final Runnable transactional) {
78+
while (true) {
79+
try {
80+
transactional.run();
81+
break;
82+
} catch (MongoException e) {
83+
System.out.println("Transaction aborted. Caught exception during transaction.");
84+
85+
if (e.hasErrorLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL)) {
86+
System.out.println("TransientTransactionError, aborting transaction and retrying ...");
87+
} else {
88+
throw e;
89+
}
90+
}
91+
}
92+
}
93+
94+
private void commitWithRetry(final ClientSession clientSession) {
95+
while (true) {
96+
try {
97+
clientSession.commitTransaction();
98+
System.out.println("Transaction committed");
99+
break;
100+
} catch (MongoException e) {
101+
// can retry commit
102+
if (e.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
103+
System.out.println("UnknownTransactionCommitResult, retrying commit operation ...");
104+
} else {
105+
System.out.println("Exception during commit ...");
106+
throw e;
107+
}
108+
}
109+
}
110+
}
111+
112+
private void updateEmployeeInfo() {
113+
MongoCollection<Document> employeesCollection = client.getDatabase("hr").getCollection("employees");
114+
MongoCollection<Document> eventsCollection = client.getDatabase("reporting").getCollection("events");
115+
116+
TransactionOptions txnOptions = TransactionOptions.builder()
117+
.readPreference(ReadPreference.primary())
118+
.readConcern(ReadConcern.MAJORITY)
119+
.writeConcern(WriteConcern.MAJORITY)
120+
.build();
121+
122+
ClientSession clientSession = client.startSession();
123+
try {
124+
clientSession.startTransaction(txnOptions);
125+
126+
employeesCollection.updateOne(clientSession,
127+
Filters.eq("employee", 3),
128+
Updates.set("status", "Inactive"));
129+
eventsCollection.insertOne(clientSession,
130+
new Document("employee", 3).append("status", new Document("new", "Inactive").append("old", "Active")));
131+
132+
commitWithRetry(clientSession);
133+
} finally {
134+
clientSession.close();
135+
}
136+
}
137+
138+
private void createCollection(final MongoClient client, final String dbName, final String collectionName) {
139+
try {
140+
client.getDatabase(dbName).createCollection(collectionName);
141+
} catch (MongoCommandException e) {
142+
if (!e.getErrorCodeName().equals("NamespaceExists")) {
143+
throw e;
144+
}
145+
}
146+
}
147+
148+
private boolean canRunTest() {
149+
if (isSharded()) {
150+
return serverVersionAtLeast(4, 1);
151+
} else if (isDiscoverableReplicaSet()) {
152+
return serverVersionAtLeast(4, 0);
153+
} else {
154+
return false;
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)