请教一个分布式事务的问题

2020-05-15 10:17:31 +08:00
 MeloForsaken

有这样一个业务,分为三步: 1.A 服务做一个 insert 。 2.通过 HTTP 向 B 服务发请求,B 服务做一个 update 。 3.A 服务对 HTTP 请求的返回结果进行判断,如果 B 服务 update 失败,做一个 DELETE(删除之前的 insert )。

Q1:请问这算 2PC 吗? Q2:算不算强一致性? Q3:和 MQ 做分布式事务对比有什么优缺点?

谢谢!

3508 次点击
所在节点    程序员
24 条回复
opengps
2020-05-15 10:48:12 +08:00
1,不懂
2,不是,没考虑意外情况导致的更新不同步
3,mq 一般来说只是削峰填谷,操作的起码是同一个主库,看你业务描述不大像同一个库,所以不太适合用来对比
vitoliu
2020-05-15 10:58:00 +08:00
3 的步骤判断可能会有问题。http/nginx 会话连接超时返回,但是对方服务已经完成更新了,就会造成数据不一致。
MQ 做分布式事务主要是 consumer 端不断重试,直到重试到最大次数就失败了,如果是数据级别的回滚还好,自己做也没啥影响。如果还有跨系统业务交互,就很麻烦了。
而 2PC 那种就相当于本地事务,不会产生脏数据。
Jacky23333
2020-05-15 11:02:28 +08:00
你这个方案有存在这样一个问题,如果 B 服务执行成功了,然后 a 突然抛异常终止了,那就造成了数据不一致的问题了
wangyanrui
2020-05-15 11:06:13 +08:00
1. 不算
2. 不是
3. 没有可比性,目前你的这种方案就不是分布式事务的解决方案,没有办法和 MQ 的这种最终一致的解决方案进行比较

没有什么是 CRUD 解决不了的,如果有,那么就是锤死产品
Jooooooooo
2020-05-15 11:07:11 +08:00
不算

不是

任何一个环节机器挂掉数据都不一致了

最后一个不懂, 接触的更多的是最终一致性, 不追求强一致
MeloForsaken
2020-05-15 11:10:43 +08:00
@vitoliu 的确是两个系统之间的业务交互,有什么更好的分布式事务解决方案吗
hbolive
2020-05-15 11:15:25 +08:00
@MeloForsaken B 再单独给个查询接口,A 对 B 进行一定次数的查询,如果查询结果为成功,则执行 A 的删除。
peyppicp
2020-05-15 11:15:57 +08:00
提供个思路,A,B 服务做好接口幂等性,出现 timeout 或者失败的 case 原地重试,兜底定时任务查补单,还有问题的人工处理,这样能干掉 99.9%的问题。
freakxx
2020-05-15 11:19:27 +08:00
@peyppicp #8

此处应 at saga 模式
lhx2008
2020-05-15 11:19:40 +08:00
算是分布式事务,但是还不够 2PC
2PC 先让对方做一步,最后提交的时候再协商确定,A 服务应该先让 B 服务 update,然后不要提交,A 服务再 insert,然后再通知 B 服务器提交,A 服务再提交。这样可以防止 A 服务 insert 掉就挂了,但是最后多多少少还是有一些挂的情况无法避免的。
MQ 本身并没有分布式事务的功能,还是业务实现
ChoateYao
2020-05-15 11:21:11 +08:00
1. 算,但是实现简陋
2. 是的,算强一致性,因为你需要阻塞当前操作
3. MQ 的一般都是最终一致性
figael
2020-05-15 11:26:28 +08:00
1: 不是 2pc,更多是 TCC 。2pc 是第一步:A 服务,B 服务 都进行 preapre ; 第二步 A 和 B 都 prepare 成功,则 commit,如果其中一个失败,则全部回滚。

2:分布式事务严格意义上,没有强一致性,只有最终一致性。

3:优点:不用重复造轮子(高可用,高性能),缺点:运维

------
分布式事务,如果是 java 系,可以看一下阿里的 seata
vitoliu
2020-05-15 11:45:47 +08:00
@MeloForsaken 系统复杂吗?如果不复杂可以先用 MQ 顶着,只要不要让脏数据影响正常的数据流转就行;如果复杂且有很多跨系统的业务交互,我不敢说让你用哪个。。毕竟 seata 我没在生产用过。
minigo
2020-05-15 11:54:23 +08:00
不算 2pc,缺少调度中心。比如当 B 成功返回后,A 挂机了,数据就不同步了。
考虑下最终一致性吧,CAP 理论。
pisc
2020-05-15 12:12:50 +08:00
@figael 什么叫分布式事务没有强一致性,不懂不要误导别人。

提供给楼主思路:好好去看书刷论文比问一些自己都一知半解就自信满满回答的人要实在的多。

比如你的问题,这样的实现是“强一致”(这里用线性一致的概念来解释)的吗?不是。因为随便都可以构造出一个不符合线性一致性的 history,首先你肯定不理解强一致性这种概念,知道问题的答案又有什么意义呢,比起这些答案,如果又不想正经去学习,最简单的方法直接从业务上去考量,抛弃这些概念。
Aresxue
2020-05-15 12:17:26 +08:00
不算 2pc,不是分两个阶段就是 2pc 的
不算
没得比
v2Geeker
2020-05-15 12:26:41 +08:00
1. 不是 2pc 。2pc 实现复杂。
2. 不是强一致性,因为存在中间状态。
3. 按你目前的实现,应该是后者好。
dog82
2020-05-15 13:09:44 +08:00
不要用 2pc,不要 autocommit,手动控制 a 的事务,a 服务 insert 后不提交,执行 b,得到结果后 a commit 或 rollback 。

这种方案依赖 b 步骤的效率,在并发不高的情况下可以这么简单做
MyStringIsNotNul
2020-05-15 13:35:49 +08:00
1. 不算
2. 不是
3. 没什么可比性,我觉得你可以参考下本地消息表的实现
yeqizhang
2020-05-15 13:57:58 +08:00
你这个方案风险很多,如果记录了日志,可以靠定时任务去处理错误的数据,或者人工处理。
和 mq 没啥好比的,可以是对你的方案的风险一个处理办法。
看你系统怎样了,我之前搞的内部管理系统,要求不高,随便搞都可以……

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

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

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

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

© 2021 V2EX