java分布式技术是什么意思(Java面试必考问题:分布式事务解决方案)java教程 / Java Web应用中的分布式事务处理与解决方案...

wufei123 发布于 2024-06-11 阅读(8)

事务管理是Java开发中经常遇到的问题,对于单体应用的事务管理我们都比较熟悉,Spring框架也提供了多种事务管理器(Spring JDBC、Hibernate、JPA等)的对接方式但是对于微服务架构的应用来说,要想实现分布式事务就不容易了。

分布式事务指事务的操作位于不同的节点上,同时需要保证事务的 ACID 特性比如在电商系统的下单场景中,库存和订单如果不在同一个节点上,就涉及到分布式事务本文主要介绍实现分布式事务的几种方案两阶段提交(2PC)方案。

两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务两阶段分为准备阶段和提交阶段准备阶段协调者询问参与者事务是否执行成功(vote request),参与者返回事务执行结果。

2PC 准备阶段提交阶段如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务(commit);否则,协调者发送通知让参与者回滚事务(abort)。

提交阶段在准备阶段,虽然参与者执行了事务,但是还未提交只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚两阶段提交理解起来并不复杂,不过也存在一些问题:同步阻塞:所有事务参与者在等待通知的时候都处于阻塞状态,无法进行其它操作。

单点问题:协调者在 2PC 中起到关键作用,也存在单点问题如果一旦在提交阶段发生故障,那么所有参与者将会一直处于等待状态数据一致性:在提交阶段,如果协调者只向部分参与者发送了 Commit 消息,此时网络突然发生异常,那么将只有部分参与者提交了事务,会造成系统数据不一致。

容错能力:2PC方案比较保守,任意一个参与者执行事务失败,会导致整个事务失败,容错能力太差Seata(Simple Extensible Autonomous Transaction Architecture。

) 是阿里开源的分布式事务框架,就是属于二阶段提交模式经常与Spring Cloud Alibaba 的服务注册中心Nacos结合使用补偿事务(TCC)方案TCC (Try-Confirm-Cancel)。

的核心思想是:针对每个操作,都要有与之对应的确认(Confirm)和补偿(Cancel)操作TCC共分为三个阶段:Try 阶段:完成所有业务的一致性检查,并预留资源Confirm 阶段:对业务系统做确认提交,如果Try阶段执行成功的话,默认 Confirm阶段是不会出错的。

Cancel 阶段:如果业务执行失败,取消执行的业务,并释放预留资源假如 A 要向 B 转账,那么:在 Try 阶段,先把 A 的资金冻结起来在 Confirm 阶段,执行转账操作,如果转账成功进行解冻。

在Cancel阶段,如果转账失败,那么将A的资金进行解冻相比2PC来说,TCC方案要更加乐观一些不过数据一致性方面要比2PC也要差一些,在Confirm和Cancel阶段,都是有失败的可能的TCC的性能要比2PC方案更优,因此更适合于互联网高并发场景。

本地消息表方案本地消息表与业务数据表处于同一个数据库中,这样就能利用本地数据库的事务机制来保证在对这两个表的操作满足事务特性,并且使用消息队列来保证最终一致性。

A节点完成写业务数据的操作之后,向本地消息表发送一个消息,本地数据库事务保证写消息操作和写业务数据操作一并完成之后A节点将该消息转发到消息队列中,如果转发成功,则将消息从本地消息表中删除,否则继续重发B节点从消息队列中读取到这个消息后,开始执行消息中的写业务数据的操作。

这个方案利用数据库的本地事务机制,避免了分布式事务,实现了最终一致性不过需要将本地消息表耦合到业务系统中MQ 事务消息方案有一些MQ产品是支持事务消息的,比如阿里的RocketMQ,支持事务消息的方式类似于二阶段提交。

思路大致如下:首先A节点发送Prepared消息到消息集群,会拿到消息的地址然后A节点执行本地事务节点提交确认消息发送请求,通过之前拿到的消息地址去访问消息,并修改状态消息集群收到消息发送确认以后,接下来就是推送消息给接收端进行消费。

RocketMQ如果确认消息发送失败,RocketMQ会定期扫描消息集群中的事务消息,如果发现了Prepared消息,就会向消息发送者确认,事务是否已经执行成功接下来RocketMQ会根据发送端设置的策略,决定是回滚还是继续发送确认消息。

这样就保证了消息发送与本地事务执行同时成功或同时失败消费端消费时可能存在消费超时或者消费失败的情况解决超时问题的思路就是一直重试,直到消费端消费成功为止可能会出现消息重复的情况,需要消费端进行去重处理如果出现消费失败,那么可能只能通过人工解决,不过出现这种情况的可能性也是极低的。

基于MQ的方案实现了最终一致性,而且不需要依赖本地数据库事务不过比较挑MQ产品,很多应用较多的MQ产品,比如RabbitMQ 和 Kafka 都不支持我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,。

欢迎大家关注、转发和评论,谢谢。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻38260