在pom.xml添加以下内容,本文基于以下版本源码进行分析。
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-seataartifactId>
<version>2.1.0.RELEASEversion>
dependency>
<dependency>
<groupId>io.seatagroupId>
<artifactId>seata-allartifactId>
<version>1.4.2version>
dependency>
直接看到spring-cloud-alibaba-seata-2.1.0.RELEASE.jar的spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.seata.rest.SeataRestTemplateAutoConfiguration,\
com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration,\
com.alibaba.cloud.seata.GlobalTransactionAutoConfiguration,\
com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration,\
com.alibaba.cloud.seata.feign.hystrix.SeataHystrixAutoConfiguration
SeataRestTemplateAutoConfiguration用于支持restTemplate的远程调用,传递XID(全局事务id)
@Configuration
public class SeataRestTemplateAutoConfiguration {
//SeataRestTemplateInterceptor交给Spring管理
@Bean
public SeataRestTemplateInterceptor seataRestTemplateInterceptor() {
return new SeataRestTemplateInterceptor();
}
//依赖注入所有的RestTemplate
@Autowired(required = false)
private Collection<RestTemplate> restTemplates;
//依赖注入拦截器
@Autowired
private SeataRestTemplateInterceptor seataRestTemplateInterceptor;
@PostConstruct
public void init() {
if (this.restTemplates != null) {
for (RestTemplate restTemplate : restTemplates) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(
restTemplate.getInterceptors());
//添加了一个拦截器
interceptors.add(this.seataRestTemplateInterceptor);
restTemplate.setInterceptors(interceptors);
}
}
}
}
public class SeataRestTemplateInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes,
ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(httpRequest);
//获取XID(threadlocal)
String xid = RootContext.getXID();
if (!StringUtils.isEmpty(xid)) {
//如果有XID则设置到request的HttpHeaders中
requestWrapper.getHeaders().add(RootContext.KEY_XID, xid);
}
return clientHttpRequestExecution.execute(requestWrapper, bytes);
}
}
SeataHandlerInterceptorConfiguration实现了WebMvcConfigurer接口,添加了Interceptor去接收请求携带过来的XID
public class SeataHandlerInterceptorConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//所有请求都拦截
registry.addInterceptor(new SeataHandlerInterceptor()).addPathPatterns("/**");
}
}
public class SeataHandlerInterceptor implements HandlerInterceptor {
private static final Logger log = LoggerFactory
.getLogger(SeataHandlerInterceptor.class);
//调用到业务代码前,绑定XID
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) {
//获取当前的XID
String xid = RootContext.getXID();
//获取请求携带过来的XID
String rpcXid = request.getHeader(RootContext.KEY_XID);
if (log.isDebugEnabled()) {
log.debug("xid in RootContext {} xid in RpcContext {}", xid, rpcXid);
}
//当前没有XID,且请求携带了XID
if (xid == null && rpcXid != null) {
//将rpcXid绑定到threadlocal中,则自己为该全局事务中的一员
RootContext.bind(rpcXid);
if (log.isDebugEnabled()) {
log.debug("bind {} to RootContext", rpcXid);
}
}
return true;
}
//调用完成结果返回以后,解绑XID
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception e) {
//获取请求携带的XID
String rpcXid = request.getHeader(RootContext.KEY_XID);
if (StringUtils.isEmpty(rpcXid)) {
return;
}
//从threadlocal中移除XID
String unbindXid = RootContext.unbind();
if (log.isDebugEnabled()) {
log.debug("unbind {} from RootContext", unbindXid);
}
if (!rpcXid.equalsIgnoreCase(unbindXid)) {
log.warn("xid in change during RPC from {} to {}", rpcXid, unbindXid);
if (unbindXid != null) {
RootContext.bind(unbindXid);
log.warn("bind {} back to RootContext", unbindXid);
}
}
}
}
GlobalTransactionAutoConfiguration主要实例化了GlobalTransactionScanner 这个bean
@Configuration
@EnableConfigurationProperties(SeataProperties.class)
public class GlobalTransactionAutoConfiguration {
private final ApplicationContext applicationContext;
private final SeataProperties seataProperties;
public GlobalTransactionAutoConfiguration(ApplicationContext applicationContext,
SeataProperties seataProperties) {
this.applicationContext = applicationContext;
this.seataProperties = seataProperties;
}
//实例化GlobalTransactionScanner
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
String applicationName = applicationContext.getEnvironment()
.getProperty("spring.application.name");
String txServiceGroup = seataProperties.getTxServiceGroup();
if (StringUtils.isEmpty(txServiceGroup)) {
txServiceGroup = applicationName + "-fescar-service-group";
seataProperties.setTxServiceGroup(txServiceGroup);
}
return new GlobalTransactionScanner(applicationName, txServiceGroup);
}
}
//获取spring.cloud.alibaba.seat.tx-service-group的属性
@ConfigurationProperties("spring.cloud.alibaba.seata")
public class SeataProperties {
// todo support config Fescar server information
/**
* Seata tx service group.default is ${spring.application.name}-fescar-service-group.
*/
private String txServiceGroup;
public String getTxServiceGroup() {
return txServiceGroup;
}
public void setTxServiceGroup(String txServiceGroup) {
this.txServiceGroup = txServiceGroup;
}
}
SeataHystrixAutoConfiguration支持hytrix拦截器远程调用时的XID传递
@Configuration
@ConditionalOnClass(HystrixCommand.class)
public class SeataHystrixAutoConfiguration {
@Bean
SeataHystrixConcurrencyStrategy seataHystrixConcurrencyStrategy() {
return new SeataHystrixConcurrencyStrategy();
}
}
public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private HystrixConcurrencyStrategy delegate;
public SeataHystrixConcurrencyStrategy() {
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
}
@Override
public <K> Callable<K> wrapCallable(Callable<K> c) {
if (c instanceof SeataContextCallable) {
return c;
}
Callable<K> wrappedCallable;
if (this.delegate != null) {
wrappedCallable = this.delegate.wrapCallable(c);
}
else {
wrappedCallable = c;
}
if (wrappedCallable instanceof SeataContextCallable) {
return wrappedCallable;
}
return new SeataContextCallable<>(wrappedCallable);
}
private static class SeataContextCallable<K> implements Callable<K> {
private final Callable<K> actual;
private final String xid;
SeataContextCallable(Callable<K> actual) {
this.actual = actual;
this.xid = RootContext.getXID();
}
@Override
public K call() throws Exception {
try {
//绑定XID
RootContext.bind(xid);
//目标方法调用
return actual.call();
}
finally {
//清除threadlocal的XID
RootContext.unbind();
}
}
}
}
SeataFeignClientAutoConfiguration用于支持feign远程调用的XID的传递
@Configuration
@ConditionalOnClass(Client.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class SeataFeignClientAutoConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnClass(name = "com.netflix.hystrix.HystrixCommand")
@ConditionalOnProperty(name = "feign.hystrix.enabled", havingValue = "true")
Feign.Builder feignHystrixBuilder(BeanFactory beanFactory) {
return SeataHystrixFeignBuilder.builder(beanFactory);
}
@Bean
@Scope("prototype")
@ConditionalOnClass(name = "com.alibaba.csp.sentinel.SphU")
@ConditionalOnProperty(name = "feign.sentinel.enabled", havingValue = "true")
Feign.Builder feignSentinelBuilder(BeanFactory beanFactory) {
return SeataSentinelFeignBuilder.builder(beanFactory);
}
@Bean
@ConditionalOnMissingBean
@Scope("prototype")
Feign.Builder feignBuilder(BeanFactory beanFactory) {
return SeataFeignBuilder.builder(beanFactory);
}
@Configuration
protected static class FeignBeanPostProcessorConfiguration {
//看这个BeanPostProcessor,用于包装feignClient传递XID
@Bean
SeataBeanPostProcessor seataBeanPostProcessor(
SeataFeignObjectWrapper seataFeignObjectWrapper) {
return new SeataBeanPostProcessor(seataFeignObjectWrapper);
}
//将原本的feignContext包装为SeataFeignContext
@Bean
SeataContextBeanPostProcessor seataContextBeanPostProcessor(
BeanFactory beanFactory) {
return new SeataContextBeanPostProcessor(beanFactory);
}
//用于调用该SeataFeignObjectWrapper的wrap方法包装feignClient
@Bean
SeataFeignObjectWrapper seataFeignObjectWrapper(BeanFactory beanFactory) {
return new SeataFeignObjectWrapper(beanFactory);
}
}
}
//SeataBeanPostProcessor
final class SeataBeanPostProcessor implements BeanPostProcessor {
private final SeataFeignObjectWrapper seataFeignObjectWrapper;
SeataBeanPostProcessor(SeataFeignObjectWrapper seataFeignObjectWrapper) {
this.seataFeignObjectWrapper = seataFeignObjectWrapper;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
//看这里,调用SeataFeignObjectWrapper的wrap方法包装feignClient
return this.seataFeignObjectWrapper.wrap(bean);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
Object wrap(Object bean) {
//将原本的feignClient包装为SeataFeignClient
//将原本的LoadBalancerFeignClient包装为SeataLoadBalancerFeignClient
if (bean instanceof Client && !(bean instanceof SeataFeignClient)) {
if (bean instanceof LoadBalancerFeignClient) {
LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean);
return new SeataLoadBalancerFeignClient(client.getDelegate(), factory(),
clientFactory(), this.beanFactory);
}
return new SeataFeignClient(this.beanFactory, (Client) bean);
}
return bean;
}
//以SeataLoadBalancerFeignClient为例,重写父类LoadBalancerFeignClient的execute方法
@Override
public Response execute(Request request, Request.Options options) throws IOException {
//获取XID,放入request的headers中
Request modifiedRequest = getModifyRequest(request);
//feignClien正常调用
return super.execute(modifiedRequest, options);
}
//如果有XID,将其封装到request中
private Request getModifyRequest(Request request) {
String xid = RootContext.getXID();
if (StringUtils.isEmpty(xid)) {
return request;
}
Map<String, Collection<String>> headers = new HashMap<>(MAP_SIZE);
headers.putAll(request.headers());
List<String> fescarXid = new ArrayList<>();
fescarXid.add(xid);
headers.put(RootContext.KEY_XID, fescarXid);
return Request.create(request.method(), request.url(), headers, request.body(),
request.charset());
}
来看到GlobalTransactionScanner 这个类,继承了AbstractAutoProxyCreator,重写了wrapIfNecessary方法和getAdvicesAndAdvisorsForBean方法
@Override
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
try {
synchronized (PROXYED_SET) {
//已经处理过的bean不在去处理
if (PROXYED_SET.contains(beanName)) {
return bean;
}
interceptor = null;
//check TCC proxy
//如果是TCC模式,TCC后续文章再讲解
if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, applicationContext)) {
//TCC interceptor, proxy bean of sofa:reference/dubbo:reference, and LocalTCC
interceptor = new TccActionInterceptor(TCCBeanParserUtils.getRemotingDesc(beanName));
ConfigurationCache.addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
(ConfigurationChangeListener)interceptor);
}
//不是TCC模式
else {
//bean可能已经生成过代理对象了
//获取目标类
Class<?> serviceInterface = SpringProxyUtils.findTargetClass(bean);
//获取目标接口
Class<?>[] interfacesIfJdk = SpringProxyUtils.findInterfaces(bean);
//判断目标类和或者目标接口的方法是否有GlobalTransactional或者GlobalLock注解
//没有这种注解,直接返回。
if (!existsAnnotation(new Class[]{serviceInterface})
&& !existsAnnotation(interfacesIfJdk)) {
return bean;
}
if (globalTransactionalInterceptor == null) {
//实例化GlobalTransactionalInterceptor
globalTransactionalInterceptor = new GlobalTransactionalInterceptor(failureHandlerHook);
ConfigurationCache.addConfigListener(
ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
(ConfigurationChangeListener)globalTransactionalInterceptor);
}
//globalTransactionalInterceptor赋值给interceptor
interceptor = globalTransactionalInterceptor;
}
LOGGER.info("Bean[{}] with name [{}] would use interceptor [{}]", bean.getClass().getName(), beanName, interceptor.getClass().getName());
//如果不是生成过的代理对象
if (!AopUtils.isAopProxy(bean)) {
//直接调用父类的方法
//父类再次调用到子类的getAdvicesAndAdvisorsForBean方法返回interceptor
//则该bean使用interceptor生成代理对象
bean = super.wrapIfNecessary(bean, beanName, cacheKey);
} else {
//已经生成了代理对象了,只需要往拦截器链中放入interceptor就可以了
AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);
//调用自己的getAdvicesAndAdvisorsForBean方法返回interceptor
//调用父类的buildAdvisors将interceptor包装为advisor返回
Advisor[] advisor = buildAdvisors(beanName, getAdvicesAndAdvisorsForBean(null, null, null));
for (Advisor avr : advisor) {
//将自己的拦截逻辑放在最前面,第一个执行
advised.addAdvisor(0, avr);
}
}
PROXYED_SET.add(beanName);
return bean;
}
} catch (Exception exx) {
throw new RuntimeException(exx);
}
}
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource customTargetSource)
throws BeansException {
//返回interceptor(GlobalTransactionalInterceptor)
return new Object[]{interceptor};
}
看到GlobalTransactionalInterceptor,必然实现了MethodInterceptor接口,来看它的invoke方法
public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
//获取到目标类
Class<?> targetClass =
methodInvocation.getThis() != null ? AopUtils.getTargetClass(methodInvocation.getThis()) : null;
//可能是接口方法对象,获取目标实现类的方法对象
Method specificMethod = ClassUtils.getMostSpecificMethod(methodInvocation.getMethod(), targetClass);
//非Object的方法
if (specificMethod != null && !specificMethod.getDeclaringClass().equals(Object.class)) {
//可能是桥接方法
final Method method = BridgeMethodResolver.findBridgedMethod(specificMethod);
//获取到GlobalTransactional注解信息
final GlobalTransactional globalTransactionalAnnotation =
getAnnotation(method, targetClass, GlobalTransactional.class);
//获取到GlobalLock注解信息
final GlobalLock globalLockAnnotation = getAnnotation(method, targetClass, GlobalLock.class);
boolean localDisable = disable || (degradeCheck && degradeNum >= degradeCheckAllowTimes);
if (!localDisable) {
//GlobalTransactional的具体执行逻辑
if (globalTransactionalAnnotation != null) {
return handleGlobalTransaction(methodInvocation, globalTransactionalAnnotation);
}
//GlobalLock的具体执行逻辑
else if (globalLockAnnotation != null) {
return handleGlobalLock(methodInvocation, globalLockAnnotation);
}
}
}
return methodInvocation.proceed();
}
Object handleGlobalTransaction(final MethodInvocation methodInvocation,
final GlobalTransactional globalTrxAnno) throws Throwable {
boolean succeed = true;
try {
return transactionalTemplate.execute(new TransactionalExecutor() {
//目标方法调用
@Override
public Object execute() throws Throwable {
return methodInvocation.proceed();
}
//获取注解的name属性,没有的话,用方法名
public String name() {
String name = globalTrxAnno.name();
if (!StringUtils.isNullOrEmpty(name)) {
return name;
}
return formatMethod(methodInvocation.getMethod());
}
//封装注解配置的属性到TransactionInfo中
@Override
public TransactionInfo getTransactionInfo() {
// reset the value of timeout
int timeout = globalTrxAnno.timeoutMills();
if (timeout <= 0 || timeout == DEFAULT_GLOBAL_TRANSACTION_TIMEOUT) {
timeout = defaultGlobalTransactionTimeout;
}
TransactionInfo transactionInfo = new TransactionInfo();
//全局事务超时时间,默认60000,配置文件全局指定client.tm.default-global-transaction-timeout(更多可配置属性,参考官网即可)
transactionInfo.setTimeOut(timeout);
transactionInfo.setName(name());
//传播属性
transactionInfo.setPropagation(globalTrxAnno.propagation());
//全局锁冲突,重试间隔,配置文件全局指定client.rm.lock.retryInterval
transactionInfo.setLockRetryInternal(globalTrxAnno.lockRetryInternal());
//全局锁冲突,重试次数配,配置文件全局指定client.rm.lock.retryTimes
transactionInfo.setLockRetryTimes(globalTrxAnno.lockRetryTimes());
Set<RollbackRule> rollbackRules = new LinkedHashSet<>();
//控制回滚的异常条件
for (Class<?> rbRule : globalTrxAnno.rollbackFor()) {
rollbackRules.add(new RollbackRule(rbRule));
}
for (String rbRule : globalTrxAnno.rollbackForClassName()) {
rollbackRules.add(new RollbackRule(rbRule));
}
for (Class<?> rbRule : globalTrxAnno.noRollbackFor()) {
rollbackRules.add(new NoRollbackRule(rbRule));
}
for (String rbRule : globalTrxAnno.noRollbackForClassName()) {
rollbackRules.add(new NoRollbackRule(rbRule));
}
transactionInfo.setRollbackRules(rollbackRules);
return transactionInfo;
}
});
} catch (TransactionalExecutor.ExecutionException e) {
//可以自己实现failureHandler接口,发生异常时,调用到自己的方法,比如发送邮件告警
TransactionalExecutor.Code code = e.getCode();
switch (code) {
case RollbackDone:
throw e.getOriginalException();
case BeginFailure:
succeed = false;
failureHandler.onBeginFailure(e.getTransaction(), e.getCause());
throw e.getCause();
//省略部分源码
}
} finally {
if (degradeCheck) {
EVENT_BUS.post(new DegradeCheckEvent(succeed));
}
}
}
public Object execute(TransactionalExecutor business) throws Throwable {
// 1. Get transactionInfo
//调用到getTransactionInfo获取事务信息
TransactionInfo txInfo = business.getTransactionInfo();
if (txInfo == null) {
throw new ShouldNeverHappenException("transactionInfo does not exist");
}
// 1.1 Get current transaction, if not null, the tx role is 'GlobalTransactionRole.Participant'.
//判断当前是否已经存在全局事务,如果已经处于全局事务中,则此时作为参与者加入全局事务中
GlobalTransaction tx = GlobalTransactionContext.getCurrent();
// 1.2 Handle the transaction propagation.
//获取传播属性
Propagation propagation = txInfo.getPropagation();
//记录被挂起的全局事务
SuspendedResourcesHolder suspendedResourcesHolder = null;
try {
switch (propagation) {
//省略部分源码
case REQUIRES_NEW:
//该情况下,要挂起之前的事务,新开启一个全局事务
// If transaction is existing, suspend it, and then begin new transaction.
if (existingTransaction(tx)) {
suspendedResourcesHolder = tx.suspend();
tx = GlobalTransactionContext.createNew();
}
// Continue and execute with new transaction
break;
//省略部分源码
case REQUIRED:
//啥都不用做
// If current transaction is existing, execute with current transaction,
// else continue and execute with new transaction.
break;
//省略部分源码
}
// 1.3 If null, create new transaction with role 'GlobalTransactionRole.Launcher'.
//XID为空情况下,第一次被调用开始,开启一个新的全局事务
if (tx == null) {
tx = GlobalTransactionContext.createNew();
}
// set current tx config to holder
//设置txInfo封装为GlobalLockConfig并放入到threadlocal中
//从threadlocal中返回之前存在的GlobalLockConfig
GlobalLockConfig previousConfig = replaceGlobalLockConfig(txInfo);
try {
// 2. If the tx role is 'GlobalTransactionRole.Launcher', send the request of beginTransaction to TC,
// else do nothing. Of course, the hooks will still be triggered.
// 事务开启
beginTransaction(txInfo, tx);
Object rs;
try {
// Do Your Business
// 目标方法调用
rs = business.execute();
} catch (Throwable ex) {
// 3. The needed business exception to rollback.
//方法调用过程发生异常,进行回滚
completeTransactionAfterThrowing(txInfo, tx, ex);
throw ex;
}
// 4. everything is fine, commit.
//事务提交
commitTransaction(tx);
return rs;
} finally {
//5. clear
//恢复之前存在的GlobalLockConfig
resumeGlobalLockConfig(previousConfig);
triggerAfterCompletion();
cleanUp();
}
} finally {
// If the transaction is suspended, resume it.
if (suspendedResourcesHolder != null) {
//如果有挂起的事务,需要恢复挂起的事务
tx.resume(suspendedResourcesHolder);
}
}
}
Object handleGlobalLock(final MethodInvocation methodInvocation,
final GlobalLock globalLockAnno) throws Throwable {
return globalLockTemplate.execute(new GlobalLockExecutor() {
//目标方法调用
@Override
public Object execute() throws Throwable {
return methodInvocation.proceed();
}
//全局锁冲突时,GlobalLock重试次数和重试间隔
@Override
public GlobalLockConfig getGlobalLockConfig() {
GlobalLockConfig config = new GlobalLockConfig();
config.setLockRetryInternal(globalLockAnno.lockRetryInternal());
config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
return config;
}
});
}
public Object execute(GlobalLockExecutor executor) throws Throwable {
boolean alreadyInGlobalLock = RootContext.requireGlobalLock();
//将RootContext的CONTEXT_HOLDER(threadlocal)的TX_LOCK设置为true
if (!alreadyInGlobalLock) {
RootContext.bindGlobalLockFlag();
}
// set my config to config holder so that it can be access in further execution
// for example, LockRetryController can access it with config holder
//获取GlobalLock的重试属性
GlobalLockConfig myConfig = executor.getGlobalLockConfig();
//设置txInfo封装为GlobalLockConfig并放入到threadlocal中
//从threadlocal中返回之前存在的GlobalLockConfig
GlobalLockConfig previousConfig = GlobalLockConfigHolder.setAndReturnPrevious(myConfig);
try {
//目标方法调用
return executor.execute();
} finally {
// only unbind when this is the root caller.
// otherwise, the outer caller would lose global lock flag
if (!alreadyInGlobalLock) {
//将RootContext的CONTEXT_HOLDER(threadlocal)的TX_LOCK移除掉
RootContext.unbindGlobalLockFlag();
}
// if previous config is not null, we need to set it back
// so that the outer logic can still use their config
if (previousConfig != null) {
//恢复之前存在的GlobalLockConfig
GlobalLockConfigHolder.setAndReturnPrevious(previousConfig);
} else {
GlobalLockConfigHolder.remove();
}
}
}
public static GlobalTransaction getCurrent() {
//获取XID
String xid = RootContext.getXID();
if (xid == null) {
//没有的话返回null
return null;
}
//已经有了XID返回DefaultGlobalTransaction
//GlobalTransactionRole.Participant事务的参与者
//GlobalStatus.Begin开始状态
return new DefaultGlobalTransaction(xid, GlobalStatus.Begin, GlobalTransactionRole.Participant);
}
public static GlobalTransaction createNew() {
return new DefaultGlobalTransaction();
}
//xid为null,GlobalTransactionRole.Launcher事务的发起者,状态为UnKnown
DefaultGlobalTransaction() {
this(null, GlobalStatus.UnKnown, GlobalTransactionRole.Launcher);
}
public SuspendedResourcesHolder suspend() throws TransactionException {
// In order to associate the following logs with XID, first get and then unbind.
//将当前的XID暂存到SuspendedResourcesHolder中
String xid = RootContext.getXID();
if (xid != null) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Suspending current transaction, xid = {}", xid);
}
RootContext.unbind();
return new SuspendedResourcesHolder(xid);
} else {
return null;
}
}
public void resume(SuspendedResourcesHolder suspendedResourcesHolder) throws TransactionException {
//将暂存的XID绑定回RootContext(threadlocal)中
if (suspendedResourcesHolder == null) {
return;
}
String xid = suspendedResourcesHolder.getXid();
RootContext.bind(xid);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Resumimg the transaction,xid = {}", xid);
}
}
private void beginTransaction(TransactionInfo txInfo, GlobalTransaction tx) throws TransactionalExecutor.ExecutionException {
try {
//空方法,自己可以扩展,实现TransactionHook接口,通过registerHook方法注册自己的TransactionHook
triggerBeforeBegin();
tx.begin(txInfo.getTimeOut(), txInfo.getName());
triggerAfterBegin();
} catch (TransactionException txe) {
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.BeginFailure);
}
}
public void begin(int timeout, String name) throws TransactionException {
//如果不是事务发起者,直接返回
if (role != GlobalTransactionRole.Launcher) {
assertXIDNotNull();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ignore Begin(): just involved in global transaction [{}]", xid);
}
return;
}
assertXIDNull();
//一般为空,事务发起者起始没有XID
String currentXid = RootContext.getXID();
if (currentXid != null) {
throw new IllegalStateException("Global transaction already exists," +
" can't begin a new global transaction, currentXid = " + currentXid);
}
//和seata服务端(TC)通信,获取XID
//seata服务端 数据库持久化模式下,此时global_table就会插入该xid数据,控制和记录全局事务
xid = transactionManager.begin(null, null, name, timeout);
//状态修改为开始
status = GlobalStatus.Begin;
//绑定XID到RootContext中,后续远程调用从这里获取到XID,放入request的header中。
RootContext.bind(xid);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Begin new global transaction [{}]", xid);
}
}
//提交
private void commitTransaction(GlobalTransaction tx) throws TransactionalExecutor.ExecutionException {
try {
triggerBeforeCommit();
tx.commit();
triggerAfterCommit();
} catch (TransactionException txe) {
// 4.1 Failed to commit
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.CommitFailure);
}
}
public void commit() throws TransactionException {
//如果是事务的参与者,啥都不用干
if (role == GlobalTransactionRole.Participant) {
// Participant has no responsibility of committing
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ignore Commit(): just involved in global transaction [{}]", xid);
}
return;
}
assertXIDNotNull();
//重试次数,在tm.commitRetryCount中配置,默认5次
int retry = COMMIT_RETRY_COUNT <= 0 ? DEFAULT_TM_COMMIT_RETRY_COUNT : COMMIT_RETRY_COUNT;
try {
while (retry > 0) {
try {
//这里向TC汇报,全局事务可以提交了。
status = transactionManager.commit(xid);
break;
} catch (Throwable ex) {
LOGGER.error("Failed to report global commit [{}],Retry Countdown: {}, reason: {}", this.getXid(), retry, ex.getMessage());
retry--;
if (retry == 0) {
throw new TransactionException("Failed to report global commit", ex);
}
}
}
} finally {
if (xid.equals(RootContext.getXID())) {
suspend();
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("[{}] commit status: {}", xid, status);
}
}
public GlobalStatus commit(String xid) throws TransactionException {
//新建全局提交请求
GlobalCommitRequest globalCommit = new GlobalCommitRequest();
//携带XID
globalCommit.setXid(xid);
//netty通信报告给TC
GlobalCommitResponse response = (GlobalCommitResponse) syncCall(globalCommit);
return response.getGlobalStatus();
}
//回滚
private void completeTransactionAfterThrowing(TransactionInfo txInfo, GlobalTransaction tx, Throwable originalException) throws TransactionalExecutor.ExecutionException {
//roll back
//判断抛出的异常是否和配置异常一致,没有配置则是Throwable类型
if (txInfo != null && txInfo.rollbackOn(originalException)) {
try {
//携带XID向告知TC全局事务需要回滚
rollbackTransaction(tx, originalException);
} catch (TransactionException txe) {
// Failed to rollback
throw new TransactionalExecutor.ExecutionException(tx, txe,
TransactionalExecutor.Code.RollbackFailure, originalException);
}
} else {
// not roll back on this exception, so commit
//提交
commitTransaction(tx);
}
}
下一期,再去看到io.seata.rm.datasource.DataSourceProxy这个类的作用。