两阶段提交遇到无法恢复也无法回滚的事务该怎么办?

2016-02-15 10:17:49 +08:00
 tabris17
以 A 账户向 B 相互转账为例。
在账户余额有限制的情况下,比如余额必须大于 0 且小于 100 。
当事务处理到 pedding 状态,完成了 A 账户的扣款,向 B 账户打款时,发现 B 帐户余额会超过 100 元,打款失败,然后回滚事务,将 A 账户之前的扣款还回时发现, A 账户余额已经发生变动,还款会导致余额超过 100 。
如果采取先打款再扣款的方式,则会碰到余额不足的情况。

碰到这种情况,该如何处理?事务挂起,然后手工干预?
5826 次点击
所在节点    MongoDB
27 条回复
hantsy
2016-02-15 13:47:22 +08:00
看成 Two phase transcation 了。。。
zacard
2016-02-15 13:49:37 +08:00
@tabris17 1 和 3 操作之间如果有对余额修改(充值),要么会检查出此次充值失败,要么就会检查出这次转账失败。原子性来保证这一点。
tabris17
2016-02-15 13:56:59 +08:00
@zacard mongo 原子性之针对单个文档的操作,这里涉及到事务隔离
palmers
2016-02-15 15:23:01 +08:00
能不能使用第三方账户转账呢? 优先检查 B 账户余额 满足立即转账否则直接退回, 第三方账户肯定可以控制不会在转账期余额被操作 这样可以吗?
tianice
2016-02-15 22:29:30 +08:00
mongo 支持原子操作,并不支持事务。也不能叫两阶段提交,两阶段提交数据库在第一次预提交成功之后,必须保证事务最终能提交或回滚。不能说预提交成功之后,让你回滚你滚不回去,让你提交提交不了,不能出现这两种情况,否则预提交没有意义。
tianice
2016-02-15 22:30:58 +08:00
涉及到钱的业务还是用关系型数据库吧,至少要保证事务一致
future0906
2016-02-16 12:41:15 +08:00
@tabris17
先冻结 A 100 块,这一百块不能交易,转出;转账给 B ,不过成功的话,直接扣除,不成功解除冻结。

银行信用卡也是采用类似模型(预授权)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/256538

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX