脑图
核心
Seata三大角色
- TC :事务协调者,netty server(服务器)
- TM :事务管理器,netty client(客户端)
- RM: 资源管理器,netty client(客户端)
@GlobalTransactional(name = "fsp-create-order" rollbackFor = Exception.class)
public void create(Order order) {
orderMapper.create(order);
//feign调用
accountService.decrease(order.getuserId(),order.getMoney());
}
- 只要方法上加了@GlobalTransactional,Seata通过aop检测到之后,就会使用TM和TC通信,注册全局事务。
- 在@GlobalTransactional涵括的代码中,不管是本服务中的sql操作,还是feign调用别的服务的sql操作,只要sql操作满足如下:insert操作,delete操作,update操作,select for update操作。 就会被seata增强,使用RM与TC通信,注册分支事务。
@GlobalTransactional 源码解析
GlobalTransactionScanner继承自AbstractAutoProxyCreator,在这里拦截到加了@GlobalTransactional的方法。
GlobalTransactionScanner
public class GlobalTransactionScanner extends AbstractAutoProxyCreator
implements InitializingBean, ApplicationContextAwareDisposableBean {
}
我们需要关注的方法如下:
- AbstractAutoProxyCreator:wrapIfNecessary(aop的核心),getAdvicesAndAdvisorsForBean(拦截器)
- InitializingBean:afterPropertiesSet(初始化TM,RM)
Spring生命周期回调
@Override
public void afterPropertiesSet() {
//是否禁止了全局事务
if (disableGlobalTransaction) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Global transaction is disabled.");
}
return;
}
//初始化netty 客户端(TM RM)
initClient();
}
初始化TM,RM
private void initClient() {
//init TM
TMClient.init(applicationId, txServiceGroup);
//init RM
RMClient.init(applicationId, txServiceGroup);
}
代码最终会调用到RpcClientBootstrap -> start
bootstrap.handler(
ChannetPipeline pipeline = ch.pipeline();
pipeline.add