事务
约 857 字大约 3 分钟
2025-03-15
MongoDB 从 4.0 版本开始支持多文档事务,这使得开发者可以在 MongoDB 中执行类似关系型数据库的事务操作,确保多个文档的读写操作具有原子性、一致性、隔离性和持久性(ACID 特性)。以下是 MongoDB 事务的简单介绍:
一、什么是事务?
MongoDB 事务允许你在一个逻辑单元中执行多个操作(如插入、更新、删除等),并确保这些操作要么全部成功,要么全部失败。事务的核心特性是 ACID:
- 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败。
- 一致性(Consistency):事务执行后,数据库的状态必须保持一致。
- 隔离性(Isolation):并发事务之间互不干扰。
- 持久性(Durability):事务提交后,数据的修改是永久性的。
二、主要使用场景
MongoDB 事务适用于以下场景:
- 转账操作:确保从一个账户扣款和向另一个账户加款的原子性。
- 订单处理:确保订单创建、库存更新和支付记录的一致性。
- 复杂业务逻辑:需要多个文档操作的场景。
三、基本用法
MongoDB 事务的使用步骤如下:
1、创建会话(Session)
事务必须在一个会话中执行。会话是客户端与 MongoDB 服务器的交互上下文。
const session = client.startSession();
2、启动事务
在会话中启动事务。
session.startTransaction();
3、执行操作
在事务中执行读写操作(如插入、更新、删除等)。所有操作必须在同一个会话中执行。
const collection = client.db("test").collection("users");
await collection.insertOne({ name: "Alice" }, { session });
await collection.updateOne(
{ name: "Alice" },
{ $set: { age: 30 } },
{ session }
);
4、提交或回滚事务
- 如果所有操作成功,提交事务:
await session.commitTransaction();
- 如果发生错误,回滚事务:
await session.abortTransaction();
5、结束会话
事务结束后,关闭会话。
session.endSession();
四、示例
以下是一个简单的 MongoDB 事务示例,模拟转账操作:
const { MongoClient } = require("mongodb");
async function run() {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);
try {
await client.connect();
const database = client.db("bank");
const accounts = database.collection("accounts");
// 创建会话
const session = client.startSession();
try {
// 启动事务
session.startTransaction();
// 转账操作:从账户 A 向账户 B 转账 100 元
const accountA = await accounts.findOne({ name: "A" }, { session });
const accountB = await accounts.findOne({ name: "B" }, { session });
// A 账户减100
await accounts.updateOne(
{ name: "A" },
{ $inc: { balance: -100 } },
{ session }
);
// B账户加00
await accounts.updateOne(
{ name: "B" },
{ $inc: { balance: 100 } },
{ session }
);
// 提交事务
await session.commitTransaction();
console.log("转账成功");
} catch (error) {
// 回滚事务
await session.abortTransaction();
console.error("转账失败:", error.message);
} finally {
// 结束会话
session.endSession();
}
} finally {
await client.close();
}
}
run().catch(console.error);
五、注意事项
- 性能开销:事务会带来额外的性能开销,尤其是在分布式集群中。
- 超时限制:默认情况下,事务的超时时间为 60 秒。
- 隔离级别:MongoDB 支持读未提交(Read Uncommitted)和读已提交(Read Committed)两种隔离级别。
- 集合限制:事务中的集合必须存在于同一个数据库中,且不能跨分片集合。
六、总结
MongoDB 事务提供了多文档操作的 ACID 特性,适用于需要强一致性的场景。通过会话、事务的启动、提交和回滚,开发者可以实现复杂的业务逻辑。然而,事务会带来性能开销,因此在使用时应遵循最佳实践,确保系统的高效性和可靠性。
更新日志
2025/8/24 08:17
查看所有更新日志
e7112
-1于