随着网站和APP的发展,对数据库的事务性处理(Transaction)的需求越来越高。数据库的事务性处理可以保证数据的一致性和完整性,遵循ACID的原则来保证数据的准确性和可靠性,防止出现脏数据。而MongoDB默认没有事务性则成为其最大的限制之一,因此在MongoDB数据库上进行事务性操作,我们需要使用类似Mongoose这样的ORM框架。
Mongoose是一种Node.js MongoDB ORM(Object-Relational Mapping)工具。它可以用JavaScript来编写MongoDB查询,并且可以处理事务性操作,以便于实现ACID原则。在Mongoose中,我们可以通过session实现事务性处理。在这篇文章中,我们将会对Mongoose中的事务处理进行详细介绍,并提供代码示例和指导意义。
什么是事务性处理
在数据库中,事务性处理可以形象地看作一个操作序列,这个序列中的操作要么全部执行,要么全部不执行,中间不允许出现任何错误。如果其中一个操作出现了错误,那么整个操作序列将会被回滚(Rollback)。在ACID的定义中,A代表原子性(Atomicity), C代表一致性(Consistency),I代表隔离性(Isolation),D代表耐久性(Durability)。事务性处理的目的就是为了维护这些原则,保证数据的准确性和一致性。
Mongoose中的事务性处理
在Mongoose中,我们可以通过session实现事务性操作。事务性操作的流程通常如下:
- 创建session
我们可以通过调用Mongoose的startSession()方法来创建session。需要注意的是,session只支持在一个MongoDB数据库连接中使用。
const session = await mongoose.startSession()
- 开始事务
通过调用session的startTransaction()方法,开启一个新的事务。
await session.startTransaction()
- 执行操作
在事务中执行任何数据操作。这些操作可以是对同一个集合的多个文档的增、删、改操作,也可以是对多个集合的操作。
await model1.create({ name: 'Jack' }, { session }) await model2.create({ age: 30 }, { session })
- 事务提交或回滚
在事务执行结束后,可以通过session的commitTransaction()方法提交事务,也可以通过abortTransaction()方法回滚事务。
await session.commitTransaction()
await session.abortTransaction()
总的来说,Mongoose中的事务性处理与一般的数据库事务性操作非常类似,但是具有更高的灵活性和可定制性。例如,你可以在一个事务中执行多个集合的操作。另外,在使用session时,还有一些需要注意的细节:
- session对象要与mongoose的模型进行关联,例如:
const session = await mongoose.startSession() const userModel = require('../models/user') const CityModel = require('../models/city') // 绑定session对象 await userModel.create([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }], { session }) await CityModel.create([{ name: 'New York', population: 8175133 }, { name: 'Los Angeles', population: 3792621 }], { session })
- session仅支持从一个MongoDB连接中创建,但该连接可以同时在多个集合上运行,例如:
const session = await mongoose.startSession() await session.withTransaction(async () => { await mongoose.model('Person').create([{ name: 'Alice', age: 25 }], { session }) await mongoose.model('Place').create([{ name: 'New York', population: 8175133 }], { session }) })
通过上述的代码可以看出,在session的使用过程中还可以使用withTransaction方法包装执行的操作。使用了withTransaction方法,那么代码中就可以省略掉明确开启和关闭事务的方法。
到这里为止,一个例子已经展示了如何在Mongoose中使用session来实现事务性操作。
-- -------------------- ---- ------- ----- -------- - -------------------- ---------------------------------------------------- - ---------------- ----- ------------------- ---- --- ----- ------------- - --- ----------------- ----- ------- -------- ------ --- ----- ------- - ------------------------- --------------- ----- -------- ----- - ----- ------- - ----- ------------------------ --------------------------- --- - ----- ---- - - ------- -- ----- -------- - --- -------------- ---- -------- ------- ----- -------- - --- -------------- ---- -------- ------- ----- -------------------- ----- -------------------- ----- -------------- - ---- ---------------- -- --------------- ---------------- -- --------------- ----- -------------------- ----- -------------------- ----- ---------------------------- --------------------- - -------- - ----- --------------------------- --------------------- ---------------- - - ---------------------------展开代码
总结
Mongoose 是一个强大的ORM工具和中间件,它可以实现事务性处理,从而支持MongoDB上的ACID性质。在开发中,难免会遇到需要对多个集合进行操作的复杂场景,这时便可以使用Mongoose的事务处理来简化代码实现以及保证数据的完整性和一致性。它的使用非常灵活,可以随时开启和关闭事务。在Mongoose中使用事务性处理,你可以轻松地实现ACID原则,避免出现脏数据,提高系统的稳定性和可靠性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651f9d1195b1f8cacd726403