# transaction **Repository Path**: interview_44/transaction ## Basic Information - **Project Name**: transaction - **Description**: 分布式事务学习 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-26 - **Last Updated**: 2023-02-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 分布式服务事务 -[1、链路追踪](#1分布式事务介绍) -[2、TCC事务与seata框架](#2TCC事务与seata框架) -[3、分布式锁实现分布式事务](#3分布式锁实现分布式事务) -[4、TCC的两阶段提交与三阶段提交](#4TCC的两阶段提交与三阶段提交) -[5、本地消息表方案](#5本地消息表方案) -[6、可靠消息最终一致性方案](#6可靠消息最终一致性方案) -[7、最大努力通知方案](#7最大努力通知方案) ### 1、分布式事务介绍: ![](./picture/1、链路追踪.png) Google的Dapper,阿里的鹰眼,大众点评的CAT,Twitter的Zipkin,LINE的pinpoint,国产的skywalking。。。 国内一般用CAT和zipkin比较多,分布式底层服务框架,接收到每一层请求调用,都要交给链路追踪系统处理一下,traceid,代表一次请求。 分布式事务设计方案:XA,TCC,可靠消息最终一致性,最大努力通知方案。 一般使用最多是TCC和可靠消息最终一致性方案。 TCC技术选型:byeTCC,himly,个人ttc框架,很多公司自己写一个小框架解决,阿里开元了fascar,seata,技术选型可以选择seata,支持springCloud与dubbo。 可靠消息最终一致性方案使用框架:robbinMQ。 方案二:tcc,try,confirm,channel 只要跟钱的业务,都是用tcc,要么全部成功要么全部失败。 难度高,但是能保证高度一致性 ### 2、TCC事务与seata框架 tcc: try,confirm,channel, 只要跟钱的业务,都是用tcc,要么全部成功要么全部失败。 难度高,但是能保证高度一致性。 seata框架: 链路中的各个事务都要跟tc进行频繁的网络通信,频繁通信会带来性能开销。可以选择基于那种存储形式存放分布式事务日志,file,磁盘,mysql。 在高并发的情况下怎么处理TTC,seata也要部署多台,但如何存放多个存储文件? ![](./picture/2、seata框架.png) 1、A服务的TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID。开启整个分布式事务。 2、传递XID,调用下一个B服务。 3、B服务的 RM 携带 XID 注册分支事务,返回 BID ,本地分支事务,事务执行成功,通知 TC ,记录回滚sql,事务执行失败,也通知TC,并且事务回滚。 4、传递XID,调用下一个C服务。 5、C服务的 RM 携带 XID 注册分支事务返回 BID ,本地分支事务,事务执行成功,通知 TC ,记录回滚sql,事务执行失败,也通知TC,并且事务回滚。 6、TM 向 TC 发起针对 XID 的全局提交或回滚决议。 7、TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。 ### 3、分布式锁实现分布式事务 redis的redisson基实现了很多高级功能,包括分布式锁:redisson.lock("product_"+1+""_stock) 对于竞争场景的分布式事务: ![](./picture/3、竞争形势的分布式事务.png) 分布式锁抗高并发: 并发几万qps,如何抗得住,秒杀场景,只要服务器有8核32G配置,1秒抗2万并发没有问题: 1、首先分段加锁,可以把资源分给10个key。 2、当请求过来,可以在10个key中随意拿一个key进行加锁,1万的qps,相当于每台服务器1000qps,流量被均匀打在每台服务器上。 3、合并扣减:拿到一个key,如果下单不够,查找另外一个key的资源,如果2个key的资源加一起足够,就要把锁合并 ### 4、TCC的两阶段提交与三阶段提交 #### 两阶段提交,一般是一个应用,应用自身有多个数据库。 ![](./picture/4、两阶段提交.png) try阶段,先冻结B跟C confirm执行 出现任何一方异常 把confirm执行删除 ![](./picture/5、三阶段提交.png) ### 5、本地消息表方案 需要大量依赖消息表,添加批量任务轮询消息表进行下一步。 ![](./picture/6、本地消息表方案.png) ### 6、可靠消息最终一致性方案 需要结合rocketMQ ![](./picture/7、可靠消息最终一致性方案.png) 1、A系统本地发送prepared消息到MQ。 2、B系统消费该消息,但是先不执行。 2.1、A系统本地尝试提交事务。 3、成功则发送confirm,失败则回滚prepare。如果消息传输失败,就一直会问消息情况,A系统的confirm成功了,一定消息发送成功。 4、A系统confirm成功,自己正常执行。 5、B系统失败之后,要重试或者通知A系统,反复重发,直到成功。 ![](./picture/9、RocketMq实现可靠消息最终一致方案.png) RocketMq实现可靠消息最终一致方案。 1、首先用户发起下单请求。服务先发送一个message到mq。 2、收到返回成功 message sucess 执行同步的服务。 3、执行中其中有返回失败的,就发送 rollback message 到MQ。执行都成功了会发送 commit message 到MQ。 4、如果half message 超时,回调服务确认,没有超时,就等待rollback或是commit,之后,给到消费者消费消息。 ### 7、最大努力通知方案 设置阈值,不断重试,一直到系统B处理成功为止。 ![](./picture/8、最大努力通知方案.png)