WriteConflict expected if a document was modified out side of the transaction if the transaction is in flight that did not happen, why?
Pls follow the steps to recreate this problem with sample code - used Java sync 5.1.2. MongoDB version : 7.0; MongoDB started in Shard server mode.
mport com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.ClientSession;
import org.bson.Document;
public class MongoDBTransactionWithClientSession{
public static void main(String[] args) {
// Connection string for MongoDB
String connectionString = "mongodb://localhost:38071/";
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
// Get the database and collections
MongoDatabase database = mongoClient.getDatabase("testdb");
MongoCollection<Document> collection = database.getCollection("testcollection");
// Define the transactional operations
Runnable transactionalCode = () -> {
MongoCollection<Document> coll = database.getCollection("testcollection");
// stop execution of below statement with break point enabled in debug mode, then change one of the field in document and save document to collection
System.out.println("Updating the document which have name is 'John Doe' , out side of this transaction, may be directly backed collection, using compass GUI");
//Resume the break point
// Update the document
coll.updateOne(new Document("name", "John Doe"), new Document("$set", new Document("age", 31)));
//expected write conflict due to this document was changed out side of the transaction after this transaction started, but commit was successful without failure.
};
try (ClientSession session = mongoClient.startSession()) {
try {
// Execute the transaction with transactional code
session.withTransaction(() -> {
transactionalCode.run();
return null; // Transactional code doesn't return any value
});
session.commitTransaction();
System.out.println("Transaction committed successfully.");
} catch (Exception e) {
session.abortTransaction();
System.err.println("Transaction failed");
e.printStackTrace();
}
} catch (Exception e) {
System.err.println("Session error: " + e.getMessage());
// Handle or log session-related errors
}
} catch (Exception e) {
System.err.println("Error connecting to MongoDB or during transaction: " + e.getMessage());
}
}
}
MongoDB server setup:
[direct: mongos] test> sh.status();
shardingVersion
{ _id: 1, clusterId: ObjectId(‘66db556bd61ed226bffdecb3’) }
shards
[
{
_id: ‘shard-1’,
host: ‘shard-1/localhost:38051,localhost:38052,localhost:38053’,
state: 1,
topologyTime: Timestamp({ t: 1725650842, i: 2 })
},
{
_id: ‘shard-2’,
host: ‘shard-2/localhost:38061,localhost:38062,localhost:38063’,
state: 1,
topologyTime: Timestamp({ t: 1725650866, i: 2 })
}
]
active mongoses
[ { ‘7.0.12’: 1 } ]
autosplit
{ ‘Currently enabled’: ‘yes’ }
balancer
{
‘Currently running’: ‘no’,
‘Currently enabled’: ‘yes’,
‘Failed balancer rounds in last 5 attempts’: 0,
‘Migration Results for the last 24 hours’: ‘No recent migrations’
}
databases
[
{
database: { _id: ‘config’, primary: ‘config’, partitioned: true },
collections: {
‘config.system.sessions’: {
shardKey: { _id: 1 },
unique: false,
balancing: true,
chunkMetadata: [ { shard: ‘shard-1’, nChunks: 1 } ],
chunks: [
{ min: { _id: MinKey() }, max: { _id: MaxKey() }, ‘on shard’: ‘shard-1’, ‘last modified’: Timestamp({ t: 1, i: 0 }) }
],
tags:
}
}
},
{
database: {
_id: ‘myDb’,
primary: ‘shard-2’,
partitioned: false,
version: {
uuid: UUID(‘69eda7f0-8747-4f02-a68f-efdd9aa3d595’),
timestamp: Timestamp({ t: 1725653851, i: 1 }),
lastMod: 1
}
},
collections: {}
},
{
database: {
_id: ‘testdb’,
primary: ‘shard-2’,
partitioned: false,
version: {
uuid: UUID(‘77f8ff1b-fa56-40b3-a4c3-06063959f8d6’),
timestamp: Timestamp({ t: 1726600809, i: 1 }),
lastMod: 1
}
},
collections: {}
}
]