作者回复: 我持怀疑态度。我个人理解,分布式事务里面,如果事务协调者,事务参与者没有什么 redo 和 undo log 之类的东西,我个人认为它们不可能达成强一致性。但是问题又来了,事务协调者还要考虑 ACID 中的 AID 问题,不仅仅是一致性。举个例子,在意图保证强一致性的场景里面,你要不要考虑隔离性的问题?一个分布式事务能不能看到另外一个分布式事务的修改? 所以,综合来说,我持怀疑态度。之前听过一点银行的技术分享,他们说的强一致性其实都是最终一致性,总是有不一致的问题。也可能是我孤陋寡闻了。
作者回复: 你这个场景我其实没有理解。就是如果 db0 是提交的话,那么 db1 也是提交,不会出现 db0 提交,db1 回顾的场景。 如果 db0 提交成功了,但是 db1 没有提交成功,那么就用 db0 的数据去修复 db1。
作者回复: 1. 这个要看业务。成功率是一个不够准确的定义,你应该说取得一致性的时间是多长,以及没有办法达成一致的比率有多高。实际上,你应该做到和你的可用性一致。比如说正常,我们都会要求最终不一致的数据,每天应该控制在个位数。太多了你手工修复很要命的。 2. 我个人认为,是 seata 里面引入的。我比较孤陋寡闻,没见着别的地方哟用。我自己理解的话喜欢把它说成是 SAGA 的自动化的特殊形态。 3. 嘿嘿,如果你的分库分表中间件做得好,那么就没有。有些分库分表中间件是语句维度来调度的,所以搞不好也引入了分布式事务。 4. 对的 5. 主要是小心并发。比如说你数据出错了,你准备去修复。但是你修复之前,可能另外一个请求又把错误的数据更新为新数据了,但是这个新数据是对的。所以最好是在修复的时候要根据更新时间、版本号之类的来判断一下,避免出现并发覆盖的问题。
作者回复: 1. 是参与者返回执行情况。 2. b 参与者如果在准备阶段就失败了,那么直接回滚,这个应该没什么疑问。问题是在 commit 阶段,如果 b 参与者 commit 失败了怎么办。那么按照两阶段提交协议的要求,b 参与者这时候是不能 commit 失败的,b 要不断重试,或者用别的手段保证自己的成功。但是,显然这也是一个不现实的要求,所以 b commit 最终失败之后,肯定要人工介入的。这你也可以看出来,又出现了不一致。从理论上来说,协调者在发现 b 死活不能提交成功之后,那么 a 提交的数据应该也要处于一种不可用的状态,可惜的是,我们也做不到。 3. 参与者可以考虑询问。但是这里有一个问题,就是你问几个人呢?比如说十个节点里面,你问了六个人,三个人告诉你提交,三个人告诉你不知道,这时候你是提交还是不提交?那三个不知道的,又该怎么办?所以整体这需要一个比较复杂的机制。