Seata简要说明
1、Seata 2PC与传统2PC的区别
-
传统2PC:
-
第一阶段:参与者执行事务操作,但不提交,仅记录
UNDO
和REDO
日志。 -
第二阶段:协调者根据第一阶段的结果决定提交或回滚。
-
如果提交,参与者应用
REDO
日志;如果回滚,参与者应用UNDO
日志。
-
-
-
Seata 2PC:
-
第一阶段:参与者执行事务操作,并提交业务数据和
UNDO_LOG
。 -
第二阶段:提交时删除
UNDO_LOG
,回滚时通过UNDO_LOG
进行反向补偿。
-
Seata的2PC机制通过在第一阶段提交业务数据和UNDO_LOG
,优化了传统2PC的性能瓶颈。第二阶段的提交操作非常快速,只需删除UNDO_LOG
即可,而回滚操作则通过UNDO_LOG
进行反向补偿。这种设计使得Seata在分布式事务场景中更加高效和灵活。
2、Seata 2PC的流程
-
一阶段:准备阶段:
-
TM(事务管理器)向TC申请开启全局事务,并生成全局事务ID(XID)。
-
RM向TC注册分支事务,并执行本地事务操作,包括写入业务数据和
UNDO_LOG
。 -
RM提交本地事务,并将执行结果上报给TC。
-
-
二阶段:提交或回滚阶段:
-
提交:TM向TC发起提交请求,TC通知所有RM提交分支事务。RM删除
UNDO_LOG
记录,完成提交。 -
回滚:如果有RM执行失败,TM向TC发起回滚请求。TC通知所有RM通过
UNDO_LOG
回滚分支事务。
-
Seata 2PC机制的核心特点
-
一阶段提交:
-
在Seata的AT模式下,业务数据和回滚日志(
UNDO_LOG
)在同一个本地事务中提交。 -
这意味着在第一阶段,分支事务已经将业务数据的变更提交到数据库中,并且同时生成了
UNDO_LOG
记录。 -
一阶段完成后,本地事务提交,释放本地锁和连接资源。
-
-
二阶段提交或回滚:
-
提交:如果全局事务成功,TC(事务协调器)会通知所有RM(资源管理器)提交分支事务。此时,RM只需删除
UNDO_LOG
记录即可。因为业务数据已经在第一阶段提交,所以第二阶段的提交操作非常快速。 -
回滚:如果全局事务失败,TC会通知所有RM回滚分支事务。RM通过
UNDO_LOG
记录生成反向SQL语句,将业务数据回滚到修改前的状态。
-
3、全局锁作用
在 Seata 的 AT模式(Auto Transaction Mode) 中,全局锁的作用是确保分布式事务的一致性,防止脏写(Dirty Write)。全局锁的生命周期贯穿整个分布式事务的执行过程。
全局锁的作用
-
防止脏写:
-
在分布式事务中,多个事务可能同时操作同一行数据。
-
全局锁确保在分布式事务提交或回滚之前,其他事务不能修改被锁定的数据。
-
-
保证隔离性:
-
全局锁确保在分布式事务完成之前,其他事务无法看到未提交的数据。
-
全局锁的生命周期
第一阶段:本地事务提交
-
业务SQL执行:
-
参与者(RM,Resource Manager)执行本地事务中的业务SQL。
-
Seata会拦截SQL,生成UNDO LOG(用于回滚的逆向SQL)和全局锁。
-
-
全局锁的获取:
-
在本地事务提交之前,Seata会向事务协调者(TC,Transaction Coordinator)申请全局锁。
-
如果全局锁获取成功,本地事务可以提交;否则,本地事务会回滚。
-
-
本地事务提交:
-
本地事务提交后,数据对本地事务可见,但对其他事务不可见(因为全局锁仍然存在)。
-
第二阶段:全局提交或回滚
-
全局提交:
-
如果所有参与者都成功,协调者(TC)向所有参与者发送全局提交请求。
-
参与者收到请求后,释放全局锁,并删除UNDO LOG。
-
此时全局事务完成,数据对其他事务可见。
-
-
全局回滚:
-
如果有参与者失败,协调者(TC)向所有参与者发送全局回滚请求。
-
参与者根据UNDO LOG生成逆向SQL,执行回滚操作。
-
回滚完成后,释放全局锁,并删除UNDO LOG。
-
全局锁的存在时间
-
第一阶段:
-
全局锁在本地事务提交之前获取,并在本地事务提交后继续存在。
-
此时数据对本地事务可见,但对其他事务不可见。
-
-
第二阶段:
-
全局锁在全局提交或回滚完成后释放。
-
在全局提交或回滚之前,全局锁一直存在,确保其他事务不能修改被锁定的数据。
-
全局锁与脏数据
-
脏写:
-
全局锁防止其他事务修改被锁定的数据,从而避免脏写。
-
例如,事务A修改了某行数据但未提交,事务B尝试修改同一行数据时会被阻塞,直到事务A释放全局锁。
-
-
脏读:
-
Seata的AT模式默认不解决脏读问题,因为本地事务提交后数据对本地事务可见。
-
如果其他事务在 Seata 的全局事务提交之前启动,那么这些事务不会看到 Seata 事务提交的数据,因为它们的读视图是在 Seata 事务提交之前创建的。
-
如果其他事务在 Seata 的全局事务提交之后启动,那么这些事务可以看到 Seata 事务提交的数据。
-
-
总结
-
全局锁在第一阶段和第二阶段都存在,确保在分布式事务完成之前,其他事务不能修改被锁定的数据。
-
全局锁的生命周期:
-
第一阶段:获取全局锁并提交本地事务。
-
第二阶段:全局提交或回滚后释放全局锁。
-
-
全局锁的主要作用是防止脏写,但默认不解决脏读问题。如果需要避免脏读,需在业务层面额外处理。
4、官方文档
Seata 是什么? | Apache Seata