- Seata 是什么
- Seata术语
- Seata常见问题
- 用户文档
- 开发者指南
- 运维指南
- 博客文章
- Seata 基于改良版雪花算法的分布式UUID生成器分析
- Seata 新特性支持 undo_log 压缩
- ConcurrentHashMap 导致的 Seata 死锁问题
- Seata 应用侧启动过程剖析 注册中心与配置中心模块
- Seata 应用侧启动过程剖析 RM & TM 如何与 TC 建立连接
- Spring Cloud 集成 Seata 分布式事务 TCC 模式
- Seata 配置管理原理解析
- seata-golang 通信模型详解
- Seata 数据源代理解析
- 分布式事务 Seata 源码-Client 端启动流程
- Mac 下的 Seata Demo 环境搭建(AT模式)
- 分布式事务 Seata 源码 - Server 端启动流程
- 分布式事务如何实现?深入解读 Seata 的 XA 模式
- Seata 极简入门
- Seata config 模块源码分析
- 源码分析 Seata-XID 传递 Dubbo 篇
- Seata tcc 模块源码分析
- 通过 AOP 动态创建/关闭 Seata 分布式事务
- Seata core 模块源码分析
- Seata 动态配置订阅与降级实现原理
- Seata 配置中心实现原理
- Docker 部署 Seata 与 Nacos 整合
- Seata 分布式事务启用 Nacos 做配置中心
- 透过源码解决 Seata AT 模式整合 Mybatis-Plus 失去 MP 特性的问题
- SpringBoot+Dubbo+MybatisPlus 整合 seata 分布式事务
- Seata 客户端需要同时启动 RM 和 TM 吗?
- Seata AT 模式启动源码分析
- 基于 Seata Saga 设计更有弹性的金融应用
- 分布式事务 Seata 及其三种模式详解
- 分布式事务中间件 Seata 的设计原理
- Seata分布式Go Server正式开源-TaaS设计简介
- Seata(Fescar)分布式事务 整合 Spring Cloud
- Fescar 与 Spring Cloud 集成源码深度剖析
- 深度剖析一站式分布式事务方案Seata-Server
- TCC适用模型与适用场景分析
- TCC 理论及设计实现指南介绍
- 如何使用Seata保证Dubbo微服务间的一致性
- Fescar分布式事务原理解析探秘
- MT 模式
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Seata API
Seata API 分为两大类:High-Level API 和 Low-Level API :
- High-Level API :用于事务边界定义、控制及事务状态查询。
- Low-Level API :用于控制事务上下文的传播。
2. High-Level API
2.1 GlobalTransaction
全局事务:包括开启事务、提交、回滚、获取当前状态等方法。
public interface GlobalTransaction {
/**
* 开启一个全局事务(使用默认的事务名和超时时间)
*/
void begin() throws TransactionException;
/**
* 开启一个全局事务,并指定超时时间(使用默认的事务名)
*/
void begin(int timeout) throws TransactionException;
/**
* 开启一个全局事务,并指定事务名和超时时间
*/
void begin(int timeout, String name) throws TransactionException;
/**
* 全局提交
*/
void commit() throws TransactionException;
/**
* 全局回滚
*/
void rollback() throws TransactionException;
/**
* 获取事务的当前状态
*/
GlobalStatus getStatus() throws TransactionException;
/**
* 获取事务的 XID
*/
String getXid();
}
2.2 GlobalTransactionContext
GlobalTransaction 实例的获取需要通过 GlobalTransactionContext:
/**
* 获取当前的全局事务实例,如果没有则创建一个新的实例。
*/
public static GlobalTransaction getCurrentOrCreate() {
GlobalTransaction tx = getCurrent();
if (tx == null) {
return createNew();
}
return tx;
}
/**
* 重新载入给定 XID 的全局事务实例,这个实例不允许执行开启事务的操作。
* 这个 API 通常用于失败的事务的后续集中处理。
* 比如:全局提交超时,后续集中处理通过重新载入该实例,通过实例方法获取事务当前状态,并根据状态判断是否需要重试全局提交操作。
*/
public static GlobalTransaction reload(String xid) throws TransactionException {
GlobalTransaction tx = new DefaultGlobalTransaction(xid, GlobalStatus.UnKnown, GlobalTransactionRole.Launcher) {
@Override
public void begin(int timeout, String name) throws TransactionException {
throw new IllegalStateException("Never BEGIN on a RELOADED GlobalTransaction. ");
}
};
return tx;
}
2.3 TransactionalTemplate
事务化模板:通过上述 GlobalTransaction 和 GlobalTransactionContext API 把一个业务服务的调用包装成带有分布式事务支持的服务。
public class TransactionalTemplate {
public Object execute(TransactionalExecutor business) throws TransactionalExecutor.ExecutionException {
// 1. 获取当前全局事务实例或创建新的实例
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
// 2. 开启全局事务
try {
tx.begin(business.timeout(), business.name());
} catch (TransactionException txe) {
// 2.1 开启失败
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.BeginFailure);
}
Object rs = null;
try {
// 3. 调用业务服务
rs = business.execute();
} catch (Throwable ex) {
// 业务调用本身的异常
try {
// 全局回滚
tx.rollback();
// 3.1 全局回滚成功:抛出原始业务异常
throw new TransactionalExecutor.ExecutionException(tx, TransactionalExecutor.Code.RollbackDone, ex);
} catch (TransactionException txe) {
// 3.2 全局回滚失败:
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.RollbackFailure, ex);
}
}
// 4. 全局提交
try {
tx.commit();
} catch (TransactionException txe) {
// 4.1 全局提交失败:
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.CommitFailure);
}
return rs;
}
}
模板方法执行的异常:ExecutionException
class ExecutionException extends Exception {
// 发生异常的事务实例
private GlobalTransaction transaction;
// 异常编码:
// BeginFailure(开启事务失败)
// CommitFailure(全局提交失败)
// RollbackFailure(全局回滚失败)
// RollbackDone(全局回滚成功)
private Code code;
// 触发回滚的业务原始异常
private Throwable originalException;
外层调用逻辑 try-catch 这个异常,根据异常编码进行处理:
- BeginFailure (开启事务失败):getCause() 得到开启事务失败的框架异常,getOriginalException() 为空。
- CommitFailure (全局提交失败):getCause() 得到全局提交失败的框架异常,getOriginalException() 为空。
- RollbackFailure (全局回滚失败):getCause() 得到全局回滚失败的框架异常,getOriginalException() 业务应用的原始异常。
- RollbackDone (全局回滚成功):getCause() 为空,getOriginalException() 业务应用的原始异常。
3. Low-Level API
3.1 RootContext
事务的根上下文:负责在应用的运行时,维护 XID 。
/**
* 得到当前应用运行时的全局事务 XID
*/
public static String getXID() {
return CONTEXT_HOLDER.get(KEY_XID);
}
/**
* 将全局事务 XID 绑定到当前应用的运行时中
*/
public static void bind(String xid) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("bind " + xid);
}
CONTEXT_HOLDER.put(KEY_XID, xid);
}
/**
* 将全局事务 XID 从当前应用的运行时中解除绑定,同时将 XID 返回
*/
public static String unbind() {
String xid = CONTEXT_HOLDER.remove(KEY_XID);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("unbind " + xid);
}
return xid;
}
/**
* 判断当前应用的运行时是否处于全局事务的上下文中
*/
public static boolean inGlobalTransaction() {
return CONTEXT_HOLDER.get(KEY_XID) != null;
}
High-Level API 的实现都是基于 RootContext 中维护的 XID 来做的。
应用的当前运行的操作是否在一个全局事务的上下文中,就是看 RootContext 中是否有 XID。
RootContext 的默认实现是基于 ThreadLocal 的,即 XID 保存在当前线程上下文中。
Low-Level API 的两个典型的应用场景:
1. 远程调用事务上下文的传播
远程调用前获取当前 XID:
String xid = RootContext.getXID();
远程调用过程把 XID 也传递到服务提供方,在执行服务提供方的业务逻辑前,把 XID 绑定到当前应用的运行时:
RootContext.bind(rpcXid);
2. 事务的暂停和恢复
在一个全局事务中,如果需要某些业务逻辑不在全局事务的管辖范围内,则在调用前,把 XID 解绑:
String unbindXid = RootContext.unbind();
待相关业务逻辑执行完成,再把 XID 绑定回去,即可实现全局事务的恢复:
RootContext.bind(unbindXid);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论