大家好,我是徒手敲代码。
在分布式系统当中,确保数据的一致性是一项至关重要的任务。两阶段提交作为分布式事务处理的核心机制之一,它主要用于解决分布式环境中多个节点间的数据同步和一致性问题,确保事务的原子性——即事务中的所有操作要么全部成功,要么全部失败。
这个机制的两个阶段,指的是准备阶段和提交/回滚阶段。
准备阶段
在这个阶段,系统中的一个协调者组件,会扮演着指挥官的角色,它向所有涉及事务的参与者发送预提交请求。每个参与者接收到请求后,会进行一系列的检查,比如确保本地资源能够满足事务提交的需求。如果一切就绪,参与者会回复协调者一个“准备好”的信号,并锁定必要的资源,以防其他事务干扰。然而,若参与者发现无法满足事务要求,比如资源不足,则会返回一个否定响应。
提交/回滚阶段
协调者依据第一阶段收集到的所有反馈,来决定事务的最终命运。如果所有参与者都已准备好,协调者会下达提交指令,各参与者将之前准备好的操作正式执行,释放资源并确认事务完成。
否则,只要有任一参与者反馈失败或未响应,协调者则命令所有已准备的参与者执行回滚操作,撤销之前的操作,恢复到事务开始前的状态,从而保证数据的一致性不被破坏。
优缺点
这个方案尽量保证了数据一致性,但是会存在几个问题:
- 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈
- 可靠性问题:如果协调者存在单点故障问题,或出现故障,提供者将一直处于锁定状态
- 数据一致性问题:阶段2中,协调者在发起提交命令的时候,有一个参与者挂了,导致A提交了,但是B没提交,那就导致数据不一致
seata优化
针对上面的缺点,seata框架提出了解决方案。
对于性能问题,seata引入全局事务ID和优化的锁机制,特别是其乐观锁与悲观锁的灵活运用,有效减少了事务处理过程中的阻塞时间,降低了对数据库资源的占用。
对于单点故障问题,seata采用集群部署的方式;
对于一致性问题,seata 通过全局事务状态的持久化存储和故障恢复机制,确保了即使在部分参与者或协调者发生故障的情况下,事务仍能最终达到一致状态。特别是通过事务快照,可以在需要时回滚到事务开始前的状态,维护了数据的一致性。
今天的分享到这里结束了。
关注公众号“徒手敲代码”,免费领取腾讯大佬推荐的Java电子书!