如何在 mongodb 事务中测试翻转功能
Posted
技术标签:
【中文标题】如何在 mongodb 事务中测试翻转功能【英文标题】:How to test roll over feature in mongo db transactions 【发布时间】:2022-01-17 23:52:40 【问题描述】:我是 MongoDB 的新手,我在我的一个应用程序中实现了事务功能,根据我的要求,我需要将数据保存到同一数据库中的不同集合中。下面是相同的代码sn-p
在 Tuple3 中,第一个元素是数据库,第二个元素是集合,第三个元素是我要保存的数据,它以 json 字符串的形式出现,我将其转换为 bson 文档
ClientSession clientSession = mongoClient.startSession();
try
clientSession.startTransaction(transactionOptions);
for (Tuple3<String, String, String> value: insertValues)
MongoCollection<Document> collection = mongoClient
.getDatabase(insertValues.f0)
.getCollection(insertValues.f1);
Document data= Document.parse(insertValues.f2);
log.info(String.format("Inserting data into database %s and collection is %s", insertValues.f0, insertValues.f1));
collection.insertOne(clientSession, data);
clientSession.commitTransaction();
catch (MongoCommandException | MongoWriteException exception)
clientSession.abortTransaction();
log.error(String.format("Exception happened while inserting record into Mongo DB rolling back the transaction " +
"and cause of exception is: %s", exception));
finally
clientSession.close();
以下是我正在使用的交易选项
TransactionOptions transactionOptions = TransactionOptions.builder().readConcern(ReadConcern.LOCAL).writeConcern(WriteConcern.W1).build();
下面是带有 MongoClientOptions 的 MongoClient 方法,我将 Mongo DB 连接字符串作为该方法的输入
public MongoClient getTransactionConnection(String connectionString)
MongoClientOptions.Builder mongoClientOptions = new MongoClientOptions.Builder()
.readConcern(ReadConcern.LOCAL)
.writeConcern(WriteConcern.W1)
.readPreference(ReadPreference.primary())
.serverSelectionTimeout(120000)
.maxWaitTime(120000)
.connectionsPerHost(10)
.connectTimeout(120000);
MongoClientURI uri = new MongoClientURI(connectionString, mongoClientOptions);
return new MongoClient(uri);
到这里为止就好了,它正在将数据插入到指定数据库下的三个不同的集合中。但是当我尝试一些负面情况时,我试图在 try 块中抛出异常,如果发生任何错误,理想情况下应该回滚该特定客户端会话的数据。
我试图通过使用计数变量来抛出异常,如果计数值等于 1,我将抛出异常,如果有任何数据写入数据库,则应该中止事务并回滚,但我看到的是写入其中一个集合并在停止程序之后引发异常,但实际上并没有回滚写入集合的数据。我在下面尝试这样的事情
ClientSession clientSession = mongoClient.startSession();
int count = 0;
try
clientSession.startTransaction(transactionOptions);
for (Tuple3<String, String, String> value: insertValues)
MongoCollection<Document> collection = mongoClient
.getDatabase(insertValues.f0)
.getCollection(insertValues.f1);
Document data= Document.parse(insertValues.f2);
log.info(String.format("Inserting data into database %s and collection is %s", insertValues.f0, insertValues.f1));
collection.insertOne(clientSession, data);
if(count == 1)
throw new MongoException("Aborting transaction.....");
count++;
clientSession.commitTransaction();
catch (MongoCommandException | MongoWriteException exception)
clientSession.abortTransaction();
log.error(String.format("Exception happened while inserting record into Mongo DB rolling back the transaction " +
"and cause of exception is: %s", exception));
finally
clientSession.close();
我不确定我哪里出错了,我使用的是使用 Azure CosmosDB Api 部署的 Mongo DB 4.0 版。请提前帮我解决这个问题。
【问题讨论】:
【参考方案1】:Cosmos DB 在单个集合的单个分区(分片)之外不支持事务。无论使用何种 API(在您的情况下为 MongoDB API),此限制都存在。这就是为什么您没有看到您所期望的行为。注意:这在Cosmos DB MongoDB compatibility docs中有所提及。
您需要提出自己的实现来管理应用内的数据一致性。
【讨论】:
以上是关于如何在 mongodb 事务中测试翻转功能的主要内容,如果未能解决你的问题,请参考以下文章
看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制之 第二部分
CSDN----先锋事务高性能,王涛谈打造超越MongoDB的NoSQL