MongoDB 如何执行事务/加锁?
参考答案:
MongoDB 支持多文档事务,从 4.0 版本开始引入了这一功能。在 MongoDB 中执行事务和在关系型数据库中执行事务的概念有些不同,但基本的思路是一致的:确保一系列的操作要么全部成功,要么全部失败。
以下是如何在 MongoDB 中执行事务的基本步骤:
- 开启一个会话 (Session)
要使用事务,首先需要开启一个会话。会话提供了在多个操作之间保持状态的能力,这对于事务是必需的。
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<username>:<password>@cluster0.mongodb.net/myFirstDatabase?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect(err => {
const session = client.startSession();
session.startTransaction();
// ... 执行操作 ...
session.commitTransaction();
session.endSession();
client.close();
});
- 在会话中执行操作
在会话中,你可以执行一系列的数据库操作。例如,你可以插入、更新或删除文档。
const collection = session.getDatabase('mydb').getCollection('mycollection');
const result = await collection.insertOne({ name: 'MongoDB' });
- 提交或中止事务
如果所有的操作都成功,你可以提交事务。否则,你可以中止事务以撤销所有在此会话中执行的操作。
// 提交事务
session.commitTransaction();
// 或中止事务
// session.abortTransaction();
-
注意事项
- 默认情况下,MongoDB 的写操作是原子的,但事务允许你组合多个这样的操作。
- 为了确保事务的原子性,MongoDB 使用了两阶段提交协议。
- 并不是所有的存储引擎都支持事务。例如,WiredTiger 存储引擎支持事务,但MMAPv1 不支持。
- 在启用事务之前,确保你的 MongoDB 集群已经配置为支持写关注 (
w=majority
) 和重试写入 (retryWrites=true
)。 - 事务可能会影响性能,因为它们在执行时需要锁定资源。因此,在设计应用时,应仔细考虑何时使用事务。
MongoDB 的事务功能提供了在多个文档或集合上执行原子操作的能力,但它与关系型数据库中的事务在某些方面有所不同。在使用前,建议深入了解其工作原理和限制。