Java 性能调优实战
刘超
前金山软件技术经理
59174 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
开篇词 (1讲)
模块一 · 概述 (2讲)
结束语 (1讲)
Java 性能调优实战
15
15
1.0x
00:00/00:00
登录|注册

42 | 电商系统的分布式事务调优

保证事务的原子性和一致性
事务的提交和回滚决议
TC、TM、RM的协作
重试调用失败的Confirm或Cancel方法
Try、Confirm、Cancel三个阶段
三阶提交:准备阶段、预处理阶段、提交或回滚操作
二阶提交:Prepare、Commit
XA规范解决ACID四个特性
DTP模型:AP、RM、TM
Seata如何避免在第二阶段发生异常要回滚到Before快照前出现脏数据
Seata是高效的分布式事务解决方案,解决性能和侵入性问题
跨服务的分布式事务可考虑TCC实现
同服务多数据源操作不同数据库的情况下可使用基于XA规范的分布式事务
Seata(Fescar)
事务补偿机制(TCC)
二阶提交和三阶提交
XA规范
不同服务不同数据库
同服务不同数据库
逻辑复杂度增加,突出的是分布式事务
业务需求和解耦业务
未做到事务的一致性
原因:购买道具更新游戏数据库,通宝在用户账户中心数据库,属于分布式事务
异常情况:购买道具成功但未扣除通宝
定位到数据库异常问题
思考题
总结
分布式事务解决方案
分布式事务的部署架构
电商系统的微服务化
分布式事务的重要性
案例:DBA完成单台数据库线上补丁后出现异常报警
电商系统的分布式事务调优

该思维导图由 AI 生成,仅供参考

你好,我是刘超。
今天的分享也是从案例开始。我们团队曾经遇到过一个非常严重的线上事故,在一次 DBA 完成单台数据库线上补丁后,系统偶尔会出现异常报警,我们的开发工程师很快就定位到了数据库异常问题。
具体情况是这样的,当玩家购买道具之后,扣除通宝时出现了异常。这种异常在正常情况下发生之后,应该是整个购买操作都需要撤销,然而这次异常的严重性就是在于玩家购买道具成功后,没有扣除通宝。
究其原因是由于购买的道具更新的是游戏数据库,而通宝是在用户账户中心数据库,在一次购买道具时,存在同时操作两个数据库的情况,属于一种分布式事务。而我们的工程师在完成玩家获得道具和扣除余额的操作时,没有做到事务的一致性,即在扣除通宝失败时,应该回滚已经购买的游戏道具。
从这个案例中,我想你应该意识到了分布式事务的重要性。
如今,大部分公司的服务基本都实现了微服务化,首先是业务需求,为了解耦业务;其次是为了减少业务与业务之间的相互影响。
电商系统亦是如此,大部分公司的电商系统都是分为了不同服务模块,例如商品模块、订单模块、库存模块等等。事实上,分解服务是一把双刃剑,可以带来一些开发、性能以及运维上的优势,但同时也会增加业务开发的逻辑复杂度。其中最为突出的就是分布式事务了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了分布式事务调优的重要性和解决方案。通过实际案例和技术原理相结合的方式,深入探讨了分布式事务的实现原理和各种方案的优缺点。其中,Seata作为一种高效的分布式事务解决方案,通过细致的事务管理和TC、TM的协作,实现了全局事务的提交或回滚。相比传统的二阶提交,Seata在第一阶段就已经将各个事务操作commit,提高了执行效率。同时,Seata通过事务协调器维护的全局写排它锁来保证事务间的写隔离,确保事务的原子性和一致性。然而,Seata的稳定性仍有待验证,例如在TC通知RM开始提交事务后,连接断开可能导致事务一致性问题。总的来说,本文通过深入案例和技术原理的介绍,为读者提供了深入了解分布式事务调优的基础知识和实际应用的指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(41)

  • 最新
  • 精选
  • G
    目前主流的做法不是通过异步消息来实现的吗。下单同步调用扣减库存接口。然后业务线监听订单状态接口实现业务。对于扣减库存如果发生超时,下单失败。商品中心监听费单消息,加回库存。来实现最终一致性。其他业务类同

    作者回复: MQ实现的分布式事务也是TCC的一种实现方式,也是主流的一种分布式解决方案

    2019-09-18
    7
    32
  • asura
    老师好,分布事务在稳定性上还存有一些问题,可能导致数据不一致。从文章中来看老师是更推荐Seata吗?如果出现问题是要人工处理吗还是?我们在实际项目实战中采用 如:下单请求调用订单服务,同一个请求中还会调用:扣减库存(商品服务)、用券或者红包(促销服务)等其他服务。在整个方法体中做控制,如果调用的其他微服务接口返回失败就抛异常回滚整个请求来保证一致性,这种老师怎么看?

    作者回复: 最新版本的Seata其实已经做的很全面了,包括数据一致性问题,单点问题,也是牺牲了性能来换取的。 你们项目中这种做法没问题,不过很多实际项目中的分布式事务是这样实现的:在保证主订单提交成功之后,其他服务调用就会通过重试机制来保证这些调用必须成功,这种方式在并发性能上会好一些。

    2020-01-30
    2
    11
  • neohope
    老师您好,是不是可以这样理解,Seata是通过TM管理全局事务,所有用Seata的AP都可以实现写的隔离,也就是对同一行数据有影响的时候,并不存在分布的A事务没有操作完毕,B事务就开始操作的情况。 Seata默认采用了很乐观的分布式策略,CAP里面优先保证了A,并没有彻底解决脏读的问题。 而如果设置为读“已提交”,那就要Seata在内存记录额外的数据,用于返回已提交的"正确数据"?而这个就又扯出内存管理或崩溃时这些"正确数据"持久化的问题,导致系统复杂度上升?这样理解对吗?

    作者回复: 是的

    2019-11-26
    8
  • QQ怪
    不太理解seata默认隔离级别为啥是未提交读,不怕脏读?还是为了保证性能才做的妥协?

    作者回复: 默认情况下,seata认为大多数分布式业务涉及到脏读的可能性比较小,所以保证了大多数场景下的高效性。 如果需要达到全局的 读已提交,seata也提供了相应的机制来达到目的。

    2019-08-28
    2
    8
  • -W.LI-
    老师好! Seata 设计通过事务协调器维护的全局写排它锁,来保证事务间的写隔离,而读写隔离级别则默认为未提交读的隔离级别。 这个全局写排他锁支持那几种锁啊? 行锁,表锁,间隙锁,元数据锁别的记不起来了 如果支持的锁粒度不够吞吐量也会降低很多吧。

    作者回复: 赞,全局写排它锁是根据resourceId + table + pks实现。

    2019-08-27
    2
    6
  • Alsace
    我一直有个问题想请问一下,如果是基于MQ实现的最终一致性,如果需要回滚,要怎么操作?

    作者回复: 常规做法是,主业务事务完成之后,其他业务通过mq通知,我们不做回滚操作,通过重试机制或者mq的内部ack机制要保证mq的消息能成功被消费掉。

    2020-01-15
    2
    4
  • 任鹏斌
    老师有个问题阿里的开源分布式方案是事务管理器是单点的,如果挂掉了会不会引起事务不一致?

    作者回复: 会的,我在文中已经提到了

    2019-09-03
    4
  • 灿烂明天
    老师好,我看网上有些是用mq消息中间件来解决分布式事务的,其实这个方案能不能解决分布式事务问题的?他的思想是基于tcc的吗?

    作者回复: 可以的,目前很多团队用过MQ实现分布式事务,也是基于TCC的思想实现。

    2019-08-28
    2
  • -W.LI-
    课后习题:全局写锁,第一阶段没有准确的提交或者回滚前,后续业务无法持有锁。我本来还想问下老师这个是怎么做到的,不过老师最后写了嘿嘿省的问了。默认读为提交,不怕脏读么? TCC协议具体每一步怎么做讲一下么老师? 已订单支付为例, try:尝试预扣处理,怎么预扣呢。用redis锁库存还是直接怎么锁。(抢购装备,游戏币和装备都在try阶段锁定。冲突大的后try,提交的时候冲突大的先commit?)。 try阶段,如果同时有多个事务进行try操作都能try成功么?如果支持try成功感觉有可能出现课后问题的情况。try这一步很重要啊,需要保证try以后,一定能提交成功,也一定能回滚。会不会有万一的?万一兜底解决是人工处理么?

    作者回复: 对的,我们首先要使用重试机制,其次保证记录日志。

    2019-08-27
    1
  • f(x)
    没太明白事物管理器具体是什么,是单独的服务还是中间件?

    作者回复: 我们可以理解为一个单独的服务。

    2020-05-20
收起评论
显示
设置
留言
41
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部