让我困惑的是 - 没有事务(不能只是告诉MongoConnection.Begin/EndTransaction之类的)。
我想使用工作单元模式,在某些情况下回滚更改。
是否仍有一种干净的方式来使用ITransaction来丰富我的存储库?
MongoDB不支持复杂的多文档事务。如果您确实需要这个功能,那么它可能不太适合您。
然而,在大多数情况下,我们发现复杂的事务并不是必需的。在MongoDB中,所有操作都针对单个文档进行原子操作,并且我们支持很好的更新修改器,这使得许多需要事务的操作变得易于实现(而且快速)。
虽然MongoDB原生不支持事务,但是你可以自己实现乐观锁事务。它们适用于工作单元。我在GitHub上编写了一个Java示例和一些说明,以便您可以轻松地在C#中重复。
MongoDB 4.0将支持多文档事务。
请注意 - 这已经改变了
using (var session = mongoDbContext.MongoDatabase.Client.StartSession())
{
var itemAuthRepo = (Repository<ItemAuthorization, ObjectId>)mongoDbContext.ItemAuthorizations;
var calendarRepo = (Repository<CalendarEvent, ObjectId>)mongoDbContext.Calendars;
if (itemAuthRepo != null && calendarRepo!=null)
{
session.StartTransaction();
try
{
itemAuthRepo.Collection.InsertOne(session, newItemAuthorization);
calendarRepo.Collection.InsertOne(session, cal);
session.CommitTransaction();
}
catch (Exception ex)
{
session.AbortTransaction();
throw;
}
}
else
{
throw new Exception("IRepository was not casted to Repository");
}
}
MongoDB从4.0版本开始支持事务,从4.4版本开始还支持在事务中创建集合。
我刚刚在由MongoDB Atlas提供的免费集群中启用并测试了MongoDB中的事务,该集群使用的是MongoDB 5.0版本。
以下设置应适用于MongoDB 4.2+版本,尽管尚未经过测试。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<properties>
<java.version>11</java.version>
<mongodb.version>4.4.0</mongodb.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.7.0</version>
</dependency>
MongoConfig.java
@Configuration
public class MongoConfig
{
@Bean
MongoTransactionManager transactionManager(MongoDatabaseFactory
mongoDatabaseFactory)
{
return new MongoTransactionManager(mongoDatabaseFactory);
}
}
然后在您想要启用事务的函数上添加 @Transactional。
这对我有效!
你可以使用 TokuMX 替代 MongoDb。
TokuMXTM是MongoDB的一个开源高性能分支,相比基本的MongoDB,它显著提高了性能和操作效率。TokuMX可以直接替换MongoDB,并提供20倍的性能提升、90%的数据库大小减少以及支持带有MVCC的ACID事务。一些记录的笔记。
虽然 MongoDB 没有事务支持,但它支持单个文档上的原子性:
MongoDB 在单个文档内具有原子操作的支持。由于嵌套文档提供的可能性,此功能为大量用例提供了支持。
此外,关于“隔离操作序列”的手册条目可能很有趣。例如:
但是,您可以使用隔离运算符来隔离影响多个文档的单个写入操作。
是的,根据数据库版本,有多种方法可以应用于MongoDB的工作单元模式。
在MongoDB 4.0之前,没有支持多文档ACID事务。然后开发人员使用“两阶段提交协议”(单个数据库)和“三阶段提交协议”(非阻塞分布式数据库)创建自己的事务层,提供了数据一致性,但不是全部或无执行以维护数据完整性。因此,这种方式降低了性能。
MongoDB 4.0已经添加了对多文档ACID事务的支持。
来源:
https://en.wikipedia.org/wiki/Two-phase_commit_protocol