Seata 介绍
介绍
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
分布式事物的理论有2PC和3PC,2PC是一种同步阻塞的协议,在协调者与参与者同时挂掉的部分特殊场景下数据可能不一致。目前大多数分布式事物的方案都是2PC,主要是实现简单,极端场景不是那么容易出现。而且很多方案是变了种的2PC,比如第一阶段就提交了的AT和saga,而不是预留资源。
几种事务模式
AT模式
Automatic (Branch) Transaction Mode。基于支持本地 ACID 事务 的 关系型数据库:
- 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
- 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
- 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。
Saata实现AT模式的写隔离需要通过一个全局锁来避免脏写、实现读隔离的读未提交或读已提交两种隔离级别。
在写隔离的时候,如果没有拿到全局锁,本地提交的同时可能有其他的全局事物也进行了修改,这样如果回滚beforeImage的数据,就会写错误。
这种方式由于使用了全局锁、本地锁性能上相对较差。
TCC模式
TCC(try confirm cancel)典型的二阶段,不依赖于底层数据资源的事务支持:
- 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
- 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
- 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。
Saga模式
这模式来源于一个论文SAGAS,saga的原来的意思是“a long story of heroic achievement”,与需要解决的问题场景”Long lived transactions (LLTs) hold on to database resources for relatively long periods of time, sigmficantly delaying the termmation of shorter and more common transactions.“有些关系,解决的问题是长事物的问题。
Seata实现的方式通过一个状态机引擎来实现,解决问题的场景是”长事务“,说明流程的节点不只一个,用状态机来解决能够实现业务逻辑的编排,编排还能配置补偿策略,是重试还是回滚。
为了提高效率,实现的时候是事件驱动的。
状态机引擎的原理:
Seata Search也会记录事物的状态,为什么还需要一个Local DB?一个原因可能是要是事件驱动的,为了保存一个本地执行的状态。在从Event Queue中取出来的时候,并不代表执行完成,如果从Event Queue取出来没有执行完,这时候机器挂掉就丢失了信息,通过local DB保留一个State的执行状态。(PS,是同步还是异步的是可以配置的)
XA模式
这XA是有个标准的规范的: The XA Specification - The Open Group Publications Catalog,这规范比Sagas更具体 ,规范描述了全局的事务管理器与局部的资源管理器之间的接口。
参考wiki,XA是更典型的2PC,从实现上看,由于规定了具体的接口,实现方式一般是按照2PC的描述的,确定同步阻塞、特定场景崩溃后可能数据不一致需要人工处理。优点就是异构的技术实现事务(规范的好处,定义好了接口)。
Since XA uses two-phase commit, the advantages and disadvantages of that protocol generally apply to XA. The main advantage is that XA (using 2PC) allows an atomic transaction across multiple heterogeneous technologies (e.g. a single transaction could encompass multiple databases from different vendors as well as an email server and a message broker), whereas traditional database transactions are limited to a single database.
The main disadvantage is that 2PC is a blocking protocol: the other servers need to wait for the transaction manager to issue a decision about whether to commit or abort each transaction. If the transaction manager goes offline while transactions are waiting for its final decision, they will be stuck and hold their database locks until the transaction manager comes online again and issues its decision. This extended holding of locks may be disruptive to other applications that are using the same databases.
Moreover, if the transaction manager crashes and its record of decisions cannot be recovered (e.g. due to a bug in how the decisions were logged, or due to data corruption on the server), manual intervention may be necessary. Many XA implementations provide an “escape hatch” for transactions to independently decide whether to commit or abort (without waiting to hear from the transaction manager), but this risks violating the atomicity guarantee and is therefore reserved for emergencies.
这模式Seata并没有支持,后续后支持,原因就是因为是严格2PC,同步阻塞的方式效率应该非常低,但有个非常好的优势就是标准化的协议,就能够有更好的兼容性,但是大厂么,轮子都造了,兼容不兼容的不是什么问题。