今天要學習的章節是《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}})
設計