一、声明式全局事务
在Seata
示例工程中,能看到@GlobalTransactional
,如下方法示例:
@GlobalTransactional
public boolean purchase(long accountId, long stockId, long quantity) {
String xid = RootContext.getXID();
LOGGER.info("New Transaction Begins: " + xid);
boolean stockResult = reduceAccount(accountId,stockId, quantity);
if (!stockResult) {
throw new RuntimeException("账号服务调用失败,事务回滚!");
}
Long orderId = createOrder(accountId, stockId, quantity);
if (orderId == null || orderId <= 0) {
throw new RuntimeException("订单服务调用失败,事务回滚!");
}
return true;
}
复制代码
purchase
方法上加上此注解,即表示此方法内的reduceAccount
和createOrder
两个微服务调用也将加入到分布式事务中,即扣除账户余额与创建订单将具有分布式事务的数据一致性保障能力。
了解 Spring 注解事务实现的话,应该也能推测出,Seata 的事务能力也可能是基于 Spring 的 AOP 机制,给标注了@GlobalTransactional
的方法做 AOP 增加,织入额外的逻辑以完成分布式事务的能力,伪代码大致如下:
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
try {
tx.begin(xxx);
...
purchase(xxx)//给purchase增加全局事务处理能力
...
tx.commit();
} catch (Exception exx) {
tx.rollback();
throw exx;
}
复制代码
二、@GlobalTransactional 注解如何被识别?
2.1 运行环境
1)引入seata-spring-boot-starter
模块
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata.version}</version>
</dependency>
复制代码
在spring.factories
中有自动装配类SeataAutoConfiguration
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
...
io.seata.spring.boot.autoconfigure.SeataAutoConfiguration
...
复制代码
此类负责处理全局事务扫描及设置,其中就有@GlobalTransactional
。
2)条件要求:
@ConditionalOnProperty(prefix = SEATA_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
@AutoConfigureAfter({SeataCoreAutoConfiguration.class})
public class SeataAutoConfiguration
复制代码
从类的自动装备条件,可看出要满足 2 个条件:
@ConditionalOnPropert