1.简化流程:preCheck
-->DBACheck1
-->DBACheck2
-->executeTask
2.CreateIndex和DataModification(DML)请求进行校验的地方
1)CreateIndex在preCheck中
2)DataModification(DML)在executeTask中,所以没有操作两次数据库
3.模拟DataModification(DML)的check
1)执行的js文件:24.js
针对DML,会将前端的用户请求写入js文件中
printjson(db.test_collection.save([{"f":1}, {"g":1}]))
printjson(db.test_collection.save({"h";1}))
2)执行语句
C:\Users\tianthe>mongo --quiet 127.0.0.1:27017/test 24.js
2018-04-11T11:03:35.493+0800 E QUERY [thread1] SyntaxError: missing : after property id @24.js:2:38
failed to load: 24.js
失败,提示有语法错误
查询数据库集合
C:\Users\tianthe>mongo --quiet 127.0.0.1:27017/test --eval "db.test_collection.find({})"
{ "_id" : ObjectId("5acd6dbc9147fe2f3f473e37"), "a" : 1 }
{ "_id" : ObjectId("5acd6dbc9147fe2f3f473e38"), "b" : 1 }
没有成功插入,说明进行了回滚,不会重复插入数据
3.一些思考
mongodb中,单个文本具有原子性。针对多文本同时插入的操作,如果需要保证事务,需要通过两阶段提交来实现,
mongodb官方文档通过例举银行转账的例子来模拟了一个两阶段提交保证事务,逻辑实现起来还是挺复杂的,但很明显,运行的js文件中,只有简单的两条sql语句是如何做到的呢
猜测:是由内置事务管理器实现
预备(prepare):保存事务信息
就绪(Ready):
尝试执行js文件中的:
printjson(db.test_collection.save([{"f":1}, {"g":1}]))
printjson(db.test_collection.save({"h";1}))
执行过程中会记录日志和rollback信息
如果成功执行(事务管理器没有收到失败或超时的消息),事务管理器会发送commit,完成执行
如果失败,就会根据记录信息进行回滚
参考:
https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/
http://zackku.com/mongo-transaction2/