mongodb在4.0之前仅保证单个文档的操作是原子性的,对于多个文档,需要使用嵌套文档的方式进行处理。对于习惯了关系型数据库开发的同学来说,这显然很方不方便,所以在4.0之后, MongoDB开始在副本集
中提供multi-document
级别的事物支持,根据官网描述,multi-documen是指
- 单个集合中的多个文档
- 跨集合的文档
- 跨DB的文档
如果你目前还没有mongo集群,可以按照Mongo学习笔记(四) 创建副本集群replication set的方式快速搭建一个测试集群。
事物提交
@Test
public void testCommit() {
// Start a session.
ClientSession clientSession=mongoclient.startSession();
// Start Transaction.
clientSession.startTransaction();
MongoCollection<Foo> collection=mongoclient.getDatabase("test").getCollection("foo",Foo.class);
int i=0;
while (i<5){
Foo foo = new Foo();
foo.setX(2.0);
foo.setY(i);
i++;
//operation with session
collection.insertOne(clientSession,foo);
}
//commit
clientSession.commitTransaction();
clientSession.close();
}
事物回滚
@Test
public void testAbbot() {
ClientSession clientSession=mongoclient.startSession();
clientSession.startTransaction();
MongoCollection<Foo> collection=mongoclient.getDatabase("test").getCollection("foo",Foo.class);
int i=0;
while (i<5){
Foo foo = new Foo();
foo.setX(11.0);
foo.setY(i);
i++;
collection.insertOne(clientSession,foo);
}
clientSession.abortTransaction();
clientSession.close();
}
在使用事物前,需要首先开启一个session,然后通过startTransaction
方法开启事物,在进行数据交互时,需要将session作为参数传入,这样后续操作才会基于同一个事物,否则事物不生效,最后通过commitTransaction
提交事物。
Transactions 和Sessions的关系
所有的Transaction都依附于Session,对于同一个session,同一时刻仅能打开一个事务,如果会话结束,事务将全部回滚