MongoDB:实现强一致性事务的必不可少之道(mongodb事务)
MongoDB 是一种新型**NoSQL**数据库,它有着一系列的优势,如在分片上的灵活性,包括一组集群内部提供冗余复制和冗余容错等特性,并且由于它在完全复制集群上保持一致性,它被很多公司用来替代关系型数据库成为旗舰数据存储引擎。但是MongoDB 不支持ACID事务,这就使得它不能满足复杂应用场景的严格一致性需求。
实现强一致性事务是MongoDB数据库完成复杂业务的必须要求。建立在MongoDB的性能之上的**Mongo-Locking算法**,可以在只有两个事务的情况下提供强一致性。它主要利用**乐观锁**和**悲观锁**。
乐观锁:乐观锁是一种基于版本号的锁定实现。每个文档都有一个_id,当文档被修改时,将文档_id副本克隆一下,并在它的_id里面引入一个版本号,然后当更新这个实体的时候去比较版本号,如果版本号相同就允许这个更新,并更新版本号,如果版本号不同就拒绝这个更新,这样就能保证实体的强一致性。
“`js
// 更新文档的乐观锁实现
db.collection.findAndModify({
query:{
_id: 3
},
update:{
$inc:{
version:1
},
$set:{
name:’foo’
}
},
new:true
});
悲观锁: 是一种基于共享锁或排他锁来保证实体完整性和可用性的锁定实现。其原理就是当一个实体被修改时,就给这个实体加锁,直到这个实体的修改操作完成,然后释放锁,这样就保证了线程安全性和原子性更新。
```js// 更新文档的悲观锁实现
db.collection.findAndModify({ query:{
_id: 3},
update:{ $set:{
name:'foo' }
},update lock:true
});
此外,强一致性事务实现还可以依靠MongoDB提供的4种不同的原子操作来实现:$inc、$set、$push、$pull。
$inc:给指定字段累加指定值,可以用来支持类似购物车功能;
$set:更新部分字段,可以正确地实现对文档的更新;
$push:追加新的内容,可以用来支持日志的追溯功能;
$pull:从文档中移除一个值,可以用来实现审计日志信息的记录。
因此,MongoDB在实现强一致性事务时,可以利用Mongo-Locking算法的乐观锁和悲观锁,还可以依靠MongoDB提供的4种不同的原子操作,为大型分布式系统管理资源提供基础支持,从而实现强一致性事务。