多文档事务到底是什么隔离级别?写冲突怎么表现?并发下怎么重试?快照隔离能不能保证业务规则?这篇在副本集上逐个实验。
事务 T1 开始后读 A.bal = 100 事务外把 A.bal 改成 150 并提交;事务外读 = 150;T1 里再读 = 100(仍是快照里的值) T1 提交后,在新的读里 A.bal = 150
事务开始后读到的是那一刻的快照,别人之后提交的修改在事务结束前看不到。
T2 的更新:4 ms 后报错 code=112(WriteConflict),errorLabels=['TransientTransactionError']
两个事务修改同一个文档,后来的直接失败:code 112 WriteConflict,带 TransientTransactionError 标签,表示可以整个重试。
T1 仍未提交 1.5 秒后,事务外的 update 完成了吗: False T1 提交后事务外的 update 才完成:总共等了 1526 ms;最终 A.bal = 201(100 + 1 + 100)
事务外的写入遇到事务里未提交的修改会等待,不会报错,直到事务提交或中止。
最终 A.bal = 1600(应为 1600);耗时 2.12 s;因 WriteConflict 额外重试了 1492 次(平均每次提交 0.93 次)
with_transaction 遇到临时性错误会重试整个回调;热点文档上平均每次提交约一次重试,结果仍然正确。
两个事务各自看到的在岗人数 [2, 2],都让自己下班了;事务结束后在岗人数 = 0(规则被破坏)
快照隔离只检测对同一文档的写冲突,检查一个条件后更新另一个文档,会出现写偏斜,业务不变式可能被破坏。
count 命令:code=263 Cannot run 'count' in a multi-document transaction. Please see http://dochub.mongodb.org/core/transa
新开一个事务:countDocuments = 2,find_one 的结果 {'_id': 'B', 'bal': 100}事务里不能用 count 命令,要用 countDocuments。