事务特性
1、原子性(Atomicity),事务期间的操作,作为一个整体,要么全部成功,要么全部失败。
2、一致性(Consistency),事务完成前后,数据仍然满足数据库完整性要求。
3、隔离性(Isolation),多个事务并行时,可以防止事务间数据相互影响。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
4、持久性(Durability),事务提交成后,数据就永久性的保存下来。
分布式事务
分布式事务,同样具备acid特性,还有分布式特性的原则描述。
1、CAP原则
一致性(Consistency) :数据在多个副本之间能够保持一致的特性。
可用性(Availablity):系统提供的服务一直处于可用的状态,每次请求都能获得正确的响应。
分区容错性(Partition tolerance):分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
2、BASE理论
BASE 是 Basically Available(基本可用) 、Soft-state(软状态) 和Eventually Consistent(最终一致性) 三个短语的缩写。
BASE 理论是对 CAP 中一致性 C 和可用性 A 权衡的结果,是基于 CAP 定理逐步演化而来的,BASE理论的核心思想是:
即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
基本可用
假如系统出现了不可预知故障,允许损失部分可用性(响应时间上的损失 或 功能上的损失),当然也不能完全不可用。
响应时间上的损失:正常情况下的搜索引擎0.5秒即返回给用户结果,而基本可用的搜索引擎可以在2秒作用返回结果。
功能上的损失:在一个电商网站上,正常情况下,用户可以顺利完成每一笔订单。但是到了大促期间,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。
软状态
软状态指允许系统中的数据存在中间状态(CAP 理论中的数据不一致),并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
最终一致性
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
CAP 是分布式系统设计理论,BASE 是 CAP 理论中 AP 方案的延伸,ACID 是数据库事务完整性的理论。
2PC(2阶段)
准备阶段:
1、协调者发送带事务信息给各个事务参与者,询问是否可提交事务
2、各事务参与者锁定资源(乐观锁or悲观锁锁定,比如select * from xx for update)
3、执行但不提交事务,主要写入undo和redo事务日志
4、反馈协调者(yes-可以提交,no-不能提交)
提交阶段:
-
提交事务(所有参与者答复yes)
1、协调者通知所有参与者提交事务(即commit请求)
2、所有参与者进行事务提交(执行commit请求),释放锁定资源
3、所有参与者反馈协调者Ack完成的消息
4、协调者收到所有Ack消息后,完成事务提交 -
中断事务(任何1个参与者答复no)
1、协调者通知所有参与者会滚事务(即rollback请求)
2、所有参与者使用undo日志回滚,并释放锁定资源
3、所有参与者反馈协调者Ack完成的消息
4、协调者收到所有Ack消息后,完成事务中断
优势
- 简单可靠:适用对一致性要求高、事务比较简单的场景(比如支付场景)。
劣势
- 阻塞:执行过程中,所有参与阻塞,资源是被锁住的。
- 单点故障:一旦协调者发生故障,参与者会一直阻塞下去,无法完成事务。
- 数据不一致:第2阶段,如果只有部分参与者收到commit请求或rollback请求,会导致数据不一致。
3PC(3阶段)
CanCommit 阶段(询问阶段):
1、协调者向所有参与者发出 CanCommit 请求,询问是否准备好提交事务。
2、参与者执行所有必要的操作。
3、反馈协调者(yes-可以提交,no-不能提交)
PreCommit 阶段(准备阶段)
-
预提交事务(所有参与者答复yes)
1、协调者通知所有参与者预提交事务(即preCommit请求)
2、各事务参与者锁定资源(乐观锁or悲观锁锁定,比如select * from xx for update)
3、执行但不提交事务,主要写入undo和redo事务日志
4、所有参与者反馈协调者Ack或No的响应消息 -
中断事务(任何1个参与者答复no 或 协调者超时还没收到所有参与者答复)
1、通知所有参与者中断事务(即abort请求)
2、参与者收到abort请求 或者超时没收到abort请求,开始中断事务处理
3、所有参与者使用undo日志回滚,并释放锁定资源
4、所有参与者反馈协调者Ack完成的消息
5、协调者收到所有Ack消息后,完成事务中断
DoCommit 阶段(提交阶段)
-
提交事务(所有参与者答复Ack)
1、协调者通知所有参与者提交事务(即doCommit请求)
2、所有参与者进行事务提交(执行doCommit请求),释放锁定资源
3、所有参与者反馈协调者Ack完成的消息
4、协调者收到所有Ack消息后,完成事务提交
5、进入第3阶段,如果参与者超时还没收到协调者doCommit或abort请求,默认提交事务 -
中断事务(任何1个参与者答复No 或 协调者超时还没收到所有参与者答复)
1、通知所有参与者中断事务(即abort请求)
2、参与者收到abort请求 或者超时没收到abort请求,开始中断事务处理
3、所有参与者使用undo日志回滚,并释放锁定资源
4、所有参与者反馈协调者Ack完成的消息
5、协调者收到所有Ack消息后,完成事务中断
3PC相比2PC
- 降低阻塞范围(相当于2PC的2/3)
- 引入超时机制,避免2PC的永久阻塞
- 解决协调者单点问题。故障恢复或新接替的协调者,可以根据准备阶段的中间状态数据,来决定最终事务如何处理
- 仍然存在数据不一致问题,因为进入第3阶段,参与者超时未收到协调者请求,默认提交事务,仍然可能导致数据不一致。
TCC(柔性事务,最终一致)
TCC本质上还是2阶段提交。相比2PC和3PC
- 不需要协调者。使用本地事务替代全局事务,避免单点问题
- 事务管理器出故障后的恢复,通过事务日志表实现
可能遇到异常情况
- try阶段异常。在try阶段异常之后,就会执行cancel阶段,此时cancel阶段是一定要保证成功的,如果cancel阶段没有执行成功,那么就要进行重试。cancel需要考虑幂等处理。
- cancel阶段异常。该异常的处理方式和try阶段异常是一样的,失败了就重试,如果一直重试失败,那么就要进行人工干预。cancel需要考虑幂等处理。
-confirm阶段异常。try阶段成功了,那么confirm一定要成功,如果失败了,那么就要进行重试,重试多次还未成功,那么就要进行人工干预 - 本地事务与TCC事务冲突。在try阶段我们添加了一个本地事务,如果这时候try阶段异常,那么本地事务就会回滚,然后会执行cancel阶段进行回滚,所以一般不要加本地事务
- 空回滚。在执行try阶段的时候,由于超时了,导致TCC就去执行cancel阶段了,但是这时候try阶段还没有执行。考虑增加表或字段,标记是否已try,避免空回滚。
- 第二阶段重复提交。不能保证confirm阶段或者cancel阶段一定能成功,如果不成功那么我们就要进行重试。所以需要考虑幂等处理。
- 放悬挂。cancel阶段比try阶段先执行,由于网络原因导致try阶段超时,这时候就会执行cancel阶段操作,等cancel阶段执行完了,这时候try才执行,虽然事务失败了,但是这个事务已经结束了,所以这时候的try方法一定不能执行。
seata
TC(Transaction Coordinator)事务协调者,维护全局事务和分支事务状态,协调全局事务的提交和回滚。
TM(Transaction Manager)事务管理器,定义全局事务范围,开始全局事务、提交或回滚全局事务
RM(Resource Manager)资源管理器,管理分支事务处理的资源,并向TC注册分支事务以及报告分支事务状态,并驱动分支事务的提交和回滚
XA模式
优势:符合ACID原则,强一致性。实现简单,无代码侵入。
劣势:一阶段锁定资源,要等事务整体提交或回滚后才能释放,性能较差。
AT模式
优势:
1、一阶段不用锁定资源,性能较好
2、没有代码侵入
劣势:
1、记录undo-log有一定开销,但性能比XA好
2、属于最终一致性,中间可能会有数据不一致情况。
相比XA模式
1、XA在一阶段会锁定资源,AT则是直接提交事务不锁定资源。
2、XA回滚以来数据库事务,AT则根据创建的undo-log内容进行回滚。
3、XA是强一致性,AT是最终一致性。
TCC
优势:
1、一阶段即可完成数据提交,释放数据库资源,性能好
2、无需像AT模式需要生成undo-log快照
3、不依赖数据库事务,通过手动补偿操作,可以用于非事务型数据库
劣势
1、有代码侵入,需要写try,confirm,cancel代码逻辑
2、软状态,属于最终一致性
3、confirm和cancel,需要考虑幂等处理
SAGA模式
长事务解决方案,由蚂蚁金服贡献。总体来说和TCC差不多,分为两个阶段。
1、一阶段将修改提交
2、二阶段则根据一阶段进行反馈,如果成功则什么都不做,反之则进行回滚补偿。
优势
1、基于事件驱动实现异步调用,性能较好,吞吐高
2、一阶段直接提交事务,无锁,性能好
3、无需先TCC那样编写不同阶段的方法
劣势
1、软状态时间不确定,时效性较差
2、无事务隔离,可能出现脏写