分布式事务概括总结

javaWEb面试回忆总结之-----分布式事务处理:https://blog.csdn.net/zhangsanfeng2009/article/details/80929745

两阶段提交协议:

  1)协调器发送消息(告诉A库增加数据,告诉B库减少数据等),并把消息写到本地。

  2)A库收到消息,执行本机事务,不提交,成功返回yes,否则返回no,并把返回的消息写到日志。

  3)协调器收集所有库返回的消息,都是yes,则发送commit消息给数据库,数据库执行提交,否则给数据库发送abort消息,数据库执行abort操作。

  注意:写日志为了故障后恢复,根据日志提交、回滚、或者再请求协调器,询问下一步做什么。

  实现基于两阶段提交的分布式事务使用Java的开源软件atomikos变得简单。但性能实在是太差,根本不适合高并发的系统。

  1)两阶段提交涉及多次节点间的网络通信,通信时间太长!
  2)事务时间相对于变长了,锁定的资源的时间也变长了,造成资源等待时间也增加好多!

  消息对列实现

  实现方式1:业务与消息耦合

  1)发生扣款时,执行提交事务,同时把扣款人,扣了多少钱,状态保存在同一数据库的表里。

  2)1中事务成功后,发送实时消息给另一个系统,另一系统执行事务处理完成,发送成功回复消息。

  3)1中系统收到恢复的消息后,删除该条消息数据。

  实现方式2:业务与消息解耦

  思路是把发送的消息,单独保存在一个服务器上,由消息队列写入或者更改。

  1)发送扣钱提交之前,发给消息服务器,消息服务器保存它。

  2)发送扣钱提交之后,向消息系统发送确认消息,消息系统给另外数据库的服务发送消息。

  3)假如扣钱提交失败,向消息系统发送取消的消息,消息系统不会给另外数据库的服务发送消息。

  4)对于没有确认发送的消息和取消发送的消息,系统需要定时检测,因为有可能是提交成功,但是mq宕机等导致。

  优点:消息数据独立存储,降低业务系统与消息系统间的耦合;
  缺点:一次消息发送需要两次请求;业务处理服务需要实现消息状态回查接口。

解决消息重复投递的问题:多由消费端消费后不能及时删除消息导致。

  假如一个扣款方,一个收款方,扣款方成功扣款后发送消息给收款方,收款方接到消息成功收款,收款成功后,应该删除这个被消费掉的消息,但是这个时候收款方的MQ服务挂了,并没有执行删除操作。重新启动后,还会继续收款,破坏了一致性。

  解决方法:收款方维护一个状态表,记录消费情况,每来一个消息,在真正执行之前先去状态表查询一遍,看是否重复消费。

  现在多用消息队列解决分布式事务问题。两阶段提交性能太差。

--------------------

java分布式事务,及解决方案:https://www.cnblogs.com/xifenglou/p/8440836.html

RocketMQ支持消息事务,其他mq需要自己实现。

A和B两个事务,A执行成功,给B发消息,假如B一直执行失败,消息会重投,指定B执行成功,B一直不成功,一致性被破坏。

可能出现短暂的不一致性。

--------------------

多数公司使用MQ解决,springboot环境下,可以使用Atomikos或Bitronix

springboot+atomikos+mysql+mybatis+druid+分布式事务:https://www.cnblogs.com/zhaojiatao/p/8407276.html

--------------------

分布式事务实践(三)--Spring的全局事务JTA:https://www.jianshu.com/p/3938e7172443

XA:事务提交协议,两段式提交

JTA(Java Transaction API):是XA在java中的实现,解决分布式系统,同时访问多个数据源时,可能出现的数据不一致问题。

  主要的原理是两阶段提交,当整个业务完成了之后只是第一阶段提交,在第二阶段提交之前会检查其他所有事务是否已经提交,如果前面出现了错误或是没有提交,那么第二阶段就不会提交,而是直接rollback操作,这样所有的事务都会做Rollback操作。

  缺点:两阶段提交;事务时间太长,锁数据太长;低性能,低吞吐量

JTA两种实现方式:外部事务管理器实现(一般是由应用服务器提供,例如JBOSS等);通过java的lib库,如Atomikos

  总结:

  1)JTA可以用于分布式系统中分布式事务的管理.原理是通过两阶段的提交.可以同时管理多个数据源的事务。

  2)XA协议是一套分布式事务管理的规范,JTA是XA协议在Java中的实现,多个数据库或是消息厂商实现JTA接口,开发人员只需要调用SpringJTA接口即可实现JTA事务管理.

  3)但是JTA也有比较严重的性能问题,由于同时操作多个数据源,如果其中一个数据源获取数据的时间过长,会导致整个请求都非常的长,因此现实中对性能要求比较高的系统较少使用JTA事务管理.

  4)常用分布式系统事务管理实现高性能和高吞吐的方式是Spring事务同步机制以及牺牲掉事务的暂时一致性,而保证事务的最终一致性。

--------------------

posted @ 2024-05-23 10:42  雷雨客  阅读(2)  评论(0编辑  收藏  举报