今天要学习的章节是《22 | 事务开发:多文档事务》,主要讲解多文档事务管理。shell
即事务内的变化没提交前不影响事务外的数据数据库
db.tx.insertMany([{ x: 1 }, { x: 2 }]); var session = db.getMongo().startSession(); session.startTransaction(); var coll = session.getDatabase('test').getCollection("tx"); coll.updateOne({x: 1}, {$set: {y: 1}}); coll.findOne({x: 1}); // 返回 {x:1, y:1} db.tx.findOne({x: 1}); // 返回 {x:1} session.abortTransaction()
事务外虽然数据已经更新,在事务内结束前,读取的数据一致是相同的。session
var session = db.getMongo().startSession(); session.startTransaction({ readConcern: {level: "snapshot"}, writeConcern: {w: "majority"}}); var coll = session.getDatabase('test').getCollection("tx"); coll.findOne({x: 1}); // 返回:{x: 1} db.tx.updateOne({x: 1}, {$set: {y: 1}}); db.tx.findOne({x: 1}); // 返回:{x: 1, y: 1} coll.findOne({x: 1}); // 返回:{x: 1} session.abortTransaction();
MongoDB 的事务错误处理机制不一样于关系数据库:性能
var session = db.getMongo().startSession(); session.startTransaction({ readConcern: {level: "snapshot"}, writeConcern: {w: "majority"}}); var coll = session.getDatabase('test').getCollection("tx");
继续使用上个实验的tx集合,开两个 mongo shell 均执行下述语句
窗口1:coll.updateOne({x: 1}, {$set: {y: 1}}); // 正常结束
窗口2:coll.updateOne({x: 1}, {$set: {y: 2}}); // 异常 – 解决方案:重启事务
学习
窗口1:第一个事务,正常提交coll.updateOne({x: 1}, {$set: {y: 1}});
窗口2:另外一个事务更新同一条数据,异常coll.updateOne({x: 1}, {$set: {y: 2}});
窗口3:事务外更新,需等待db.tx.updateOne({x: 1}, {$set: {y: 3}})
设计