MongoDB 的事务支持是在其 4.0 版本中引入的。MongoDB 事务具有 ACID 特性,可以保证数据的一致性、隔离性、持久性和原子性。本文将详细介绍 MongoDB 事务的基本概念、使用方法和实例。
事务的概念
事务是一组数据库操作,它们被视为单个逻辑工作单元并且必须被全部完成或全部回滚。事务具有以下 ACID 特性:
- 原子性(Atomicity):事务中的所有操作被视为单个原子操作,它们要么全部成功,要么全部失败。
- 一致性(Consistency):事务开始之前和事务结束之后,数据库都必须处于一致的状态。
- 隔离性(Isolation):并发执行的事务之间是相互隔离的,一个事务的结果对其他事务是不可见的。
- 持久性(Durability):一旦事务提交成功,它所做的修改必须被永久保存到数据库中,即使出现系统故障也不能丢失。
MongoDB 的事务支持
MongoDB 4.0 版本引入了多文档事务支持,可以在一个事务中对多个文档进行修改操作。MongoDB 4.2 版本增加了对副本集的事务支持。MongoDB 4.4 版本则进一步完善了事务支持,引入了基于 read concern 和 write concern 的事务控制,以及在分片集群上实现全局事务的能力。
事务支持对于 MongoDB 来说是一个相对较新的功能,因此需要使用支持事务的版本,并且还有一些限制。例如,事务不支持针对具有不同分片键的分片集合的写入操作。事务还需要使用 WiredTiger 存储引擎,并且只支持在一个副本集中运行的节点之间进行事务操作。
事务的使用
MongoDB 事务使用起来与传统关系型数据库类似,具有类似的语法和语义。以下是一个简单的 MongoDB 事务示例:
代码语言:javascript复制const session = client.startSession();
session.startTransaction();
try {
const coll1 = client.db("test").collection("coll1");
const coll2 = client.db("test").collection("coll2");
await coll1.insertOne({ _id: 1, a: 1 }, { session });
await coll2.insertOne({ _id: 1, b: 1 }, { session });
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
session.endSession();
}
在此示例中,我们使用 startSession()
方法创建一个会话对象,然后调用 startTransaction()
方法开始一个事务。在事务中我们向两个不同的集合 coll1
和 coll2
中插入一条文档。在完成事务操作之后,我们调用 commitTransaction()
方法提交事务。如果事务中的任何操作失败,我们可以调用 abortTransaction()
方法回滚事务。最后,我们调用 endSession()
方法关闭会话对象。
在上面的示例中,我们还可以指定 read concern 和 write concern 来控制事务的行为。read concern 控制事务读取的一致性级别,write concern 控制事务提交后数据的持久性。例如,以下示例使用 majority
read concern 和 majority
write concern:
const session = client.startSession({ readConcern: { level: "majority" } });
session.startTransaction({ writeConcern: { w: "majority" } });
try {
// ...
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
session.endSession();
}
在这个示例中,我们创建了一个带有 majority
read concern 的会话对象,并在开始事务时指定了 majority
write concern。