自动配置类
SeataAutoConfiguration
@ComponentScan(basePackages = {"io.seata.spring.boot.autoconfigure.properties"})
@ConditionalOnProperty(
prefix = "seata",
name = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
@Configuration
@EnableConfigurationProperties({SeataProperties.class})
public class SeataAutoConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(SeataAutoConfiguration.class);
@Autowired
private SeataProperties seataProperties;
public SeataAutoConfiguration() {
}
@Bean
public SpringUtils springUtils() {
return new SpringUtils();
}
@Bean
@DependsOn({"springUtils"})
@ConditionalOnMissingBean({GlobalTransactionScanner.class})
public GlobalTransactionScanner globalTransactionScanner() {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Automatically configure Seata");
}
return new GlobalTransactionScanner(this.seataProperties.getApplicationId(), this.seataProperties.getTxServiceGroup());
}
}
SeataProperties:seata配置属性
@Component
@ConfigurationProperties(prefix = "seata")
@EnableConfigurationProperties({SpringCloudAlibabaConfiguration.class})
public class SeataProperties {
private boolean enabled = true;
private String applicationId;
private String txServiceGroup;
@Autowired
private SpringCloudAlibabaConfiguration springCloudAlibabaConfiguration;
public SeataProperties() {
}
public boolean isEnabled() {
return this.enabled;
}
public SeataProperties setEnabled(boolean enabled) {
this.enabled = enabled;
return this;
}
public String getApplicationId() {
if (null == this.applicationId) {
this.applicationId = this.springCloudAlibabaConfiguration.getApplicationId();
}//如果没有设置,默认去springCloudAlibanaConfiguration中的applicationId值
return this.applicationId;
}
public SeataProperties setApplicationId(String applicationId) {
this.applicationId = applicationId;
return this;
}
public String getTxServiceGroup() {
if (null == this.txServiceGroup) {
this.txServiceGroup = this.springCloudAlibabaConfiguration.getTxServiceGroup();
}//如果没有设置,默认去springCloudAlibanaConfiguration中的txServiceGroup值
return this.txServiceGroup;
}
public SeataProperties setTxServiceGroup(String txServiceGroup) {
this.txServiceGroup = txServiceGroup;
return this;
}
}
SpringCloudAlibabaConfiguration:配置applicationId、txServiceGroup属性
@ConfigurationProperties(prefix = "spring.cloud.alibaba.seata")
public class SpringCloudAlibabaConfiguration implements ApplicationContextAware {
private static final Logger LOGGER = LoggerFactory.getLogger(SpringCloudAlibabaConfiguration.class);
private static final String SPRING_APPLICATION_NAME_KEY = "spring.application.name";
private static final String DEFAULT_SPRING_CLOUD_SERVICE_GROUP_POSTFIX = "-seata-service-group";
private String applicationId;
private String txServiceGroup;
private ApplicationContext applicationContext;
public SpringCloudAlibabaConfiguration() {
}
public String getApplicationId() {
if (null == this.applicationId) {
this.applicationId = this.applicationContext.getEnvironment().getProperty("spring.application.name");
}//如果没有设置,默认为spring.application.name的值
return this.applicationId;
}
public String getTxServiceGroup() {
if (null == this.txServiceGroup) {
String applicationId = this.getApplicationId();
if (null == applicationId) {
LOGGER.warn("{} is null, please set its value", "spring.application.name");
}
this.txServiceGroup = applicationId + "-seata-service-group";
}//如果没有设置,默认为spring.application.name的值+"-seata=service-group"
return this.txServiceGroup;
}
public void setTxServiceGroup(String txServiceGroup) {
this.txServiceGroup = txServiceGroup;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
GlobalTransactionScanner:全局事务扫描
public class GlobalTransactionScanner extends AbstractAutoProxyCreator implements InitializingBean, ApplicationContextAware, DisposableBean {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalTransactionScanner.class);
private static final int AT_MODE = 1;
private static final int MT_MODE = 2;
private static final int ORDER_NUM = 1024;
private static final int DEFAULT_MODE = 3;
private static final Set PROXYED_SET = new HashSet();
private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
private MethodInterceptor interceptor;
private final String applicationId;
private final String txServiceGroup;
private final int mode;
private final boolean disableGlobalTransaction;
private final FailureHandler failureHandlerHook;
private ApplicationContext applicationContext;
public GlobalTransactionScanner(String txServiceGroup) {
this(txServiceGroup, txServiceGroup, 3);
}
public GlobalTransactionScanner(String txServiceGroup, int mode) {
this(txServiceGroup, txServiceGroup, mode);
}
public GlobalTransactionScanner(String applicationId, String txServiceGroup) {
this(applicationId, txServiceGroup, 3);
}
public GlobalTransactionScanner(String applicationId, String txServiceGroup, int mode) {
this(applicationId, txServiceGroup, mode, DEFAULT_FAIL_HANDLER);
}
public GlobalTransactionScanner(String applicationId, String txServiceGroup, FailureHandler failureHandlerHook) {
this(applicationId, txServiceGroup, 3, failureHandlerHook);
}
public GlobalTransactionScanner(String applicationId, String txServiceGroup, int mode, FailureHandler failureHandlerHook) {
this.disableGlobalTransaction = ConfigurationFactory.getInstance().getBoolean("service.disableGlobalTransaction", false);
this.setOrder(1024);
this.setProxyTargetClass(true);
this.applicationId = applicationId;
this.txServiceGroup = txServiceGroup;
this.mode = mode;
this.failureHandlerHook = failureHandlerHook;
}
public void destroy() {
ShutdownHook.getInstance().destroyAll();
}
private void initClient() {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Initializing Global Transaction Clients ... ");
}
if (!StringUtils.isNullOrEmpty(this.applicationId) && !StringUtils.isNullOrEmpty(this.txServiceGroup)) {
TMClient.init(this.applicationId, this.txServiceGroup);
//初始化事务管理器transaction manager
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Transaction Manager Client is initialized. applicationId[" + this.applicationId + "] txServiceGroup[" + this.txServiceGroup + "]");
}
RMClient.init(this.applicationId, this.txServiceGroup);
//初始化资源管理器resource manager
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Resource Manager is initialized. applicationId[" + this.applicationId + "] txServiceGroup[" + this.txServiceGroup + "]");
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Global Transaction Clients are initialized. ");
}
this.registerSpringShutdownHook(); //注册shutDownHook,关机前释放相关资源
} else {
throw new IllegalArgumentException("applicationId: " + this.applicationId + ", txServiceGroup: " + this.txServiceGroup);
}
}
private void registerSpringShutdownHook() {
if (this.applicationContext instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext)this.applicationContext).registerShutdownHook();
ShutdownHook.removeRuntimeShutdownHook();
}
ShutdownHook.getInstance().addDisposable(TmRpcClient.getInstance(this.applicationId, this.txServiceGroup));
//关机前释放事务管理器transaction manager
ShutdownHook.getInstance().addDisposable(RmRpcClient.getInstance(this.applicationId, this.txServiceGroup));
//关机前释放资源管理器resource manager
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//创建代理对象
if (this.disableGlobalTransaction) {
return bean; //如果禁止全局事务,直接返回bean
} else {
try {
synchronized(PROXYED_SET) {
if (PROXYED_SET.contains(beanName)) {
return bean; //如果已经创建beanName的代理对象,直接返回bean
} else {
this.interceptor = null;
if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, this.applicationContext)) {
this.interceptor = new TccActionInterceptor(TCCBeanParserUtils.getRemotingDesc(beanName));
//tcc模式,拦截器为TccActionInterceptor
} else {
Class> serviceInterface = SpringProxyUtils.findTargetClass(bean);
Class>[] interfacesIfJdk = SpringProxyUtils.findInterfaces(bean);
if (!this.existsAnnotation(new Class[]{serviceInterface}) && !this.existsAnnotation(interfacesIfJdk)) {
return bean;
}
if (this.interceptor == null) {
this.interceptor = new GlobalTransactionalInterceptor(this.failureHandlerHook);
//at模式,拦截器为GlobalTransactionalInterceptor
ConfigurationFactory.getInstance().addConfigListener("service.disableGlobalTransaction", (ConfigurationChangeListener)this.interceptor);
}
}
LOGGER.info("Bean[" + bean.getClass().getName() + "] with name [" + beanName + "] would use interceptor [" + this.interceptor.getClass().getName() + "]");
if (!AopUtils.isAopProxy(bean)) {
bean = super.wrapIfNecessary(bean, beanName, cacheKey);
} else {
AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);
Advisor[] advisor = this.buildAdvisors(beanName, this.getAdvicesAndAdvisorsForBean((Class)null, (String)null, (TargetSource)null));
Advisor[] var7 = advisor;
int var8 = advisor.length;
for(int var9 = 0; var9 < var8; ++var9) {
Advisor avr = var7[var9];
advised.addAdvisor(0, avr);
}
}
PROXYED_SET.add(beanName);
return bean;
}
}
} catch (Exception var13) {
throw new RuntimeException(var13);
}
}
}
private boolean existsAnnotation(Class>[] classes) {//判断是否含有注解
if (classes != null && classes.length > 0) {
Class[] var2 = classes;
int var3 = classes.length;
for(int var4 = 0; var4 < var3; ++var4) {
Class clazz = var2[var4];
if (clazz != null) {
Method[] methods = clazz.getMethods();
Method[] var7 = methods;
int var8 = methods.length;
for(int var9 = 0; var9 < var8; ++var9) {
Method method = var7[var9];
GlobalTransactional trxAnno = (GlobalTransactional)method.getAnnotation(GlobalTransactional.class);
if (trxAnno != null) {
return true;
}//如果方法上标注注解@GlobalTransactional,返回true
GlobalLock lockAnno = (GlobalLock)method.getAnnotation(GlobalLock.class);
if (lockAnno != null) {
return true;
}//如果方法上标注注解@GlobalLock,返回true
}
}
}
}
return false;
}//方法上没有注解@GlobalTransactional、@GlobalLock,返回false
private MethodDesc makeMethodDesc(GlobalTransactional anno, Method method) {
return new MethodDesc(anno, method);
}
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource customTargetSource) throws BeansException {
return new Object[]{this.interceptor};
}
public void afterPropertiesSet() {
if (this.disableGlobalTransaction) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Global transaction is disabled.");
}
} else {
this.initClient();
}
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
this.setBeanFactory(applicationContext);
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof DataSourceProxy && ConfigurationFactory.getInstance().getBoolean("client.support.spring.datasource.autoproxy", false)) {
throw new ShouldNeverHappenException("Auto proxy of DataSource can't be enabled as you've created a DataSourceProxy bean.Please consider removing DataSourceProxy bean or disabling auto proxy of DataSource.");
} else {
return super.postProcessBeforeInitialization(bean, beanName);
}
}
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
if (bean instanceof DataSource && !(bean instanceof DataSourceProxy) && ConfigurationFactory.getInstance().getBoolean("client.support.spring.datasource.autoproxy", false)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Auto proxy of [{}]", beanName);
}
final DataSourceProxy dataSourceProxy = DataSourceProxyHolder.get().putDataSource((DataSource)bean);
Class>[] interfaces = SpringProxyUtils.getAllInterfaces(bean);
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = BeanUtils.findDeclaredMethod(DataSourceProxy.class, method.getName(), method.getParameterTypes());
if (null != m) {
return m.invoke(dataSourceProxy, args);
} else {
boolean oldAccessible = method.isAccessible();
Object var6;
try {
method.setAccessible(true);
var6 = method.invoke(bean, args);
} finally {
method.setAccessible(oldAccessible);
}
return var6;
}
}
});
} else {
return super.postProcessAfterInitialization(bean, beanName);
}
}
}
TccActionInterceptor:tcc模式拦截器
public class TccActionInterceptor implements MethodInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(TccActionInterceptor.class);
private ActionInterceptorHandler actionInterceptorHandler = new ActionInterceptorHandler();
protected RemotingDesc remotingDesc;
public TccActionInterceptor() {
}
public TccActionInterceptor(RemotingDesc remotingDesc) {
this.remotingDesc = remotingDesc;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
if (!RootContext.inGlobalTransaction()) {
return invocation.proceed(); //如果没有开启全局事务,不做处理继续执行
} else {
Method method = this.getActionInterfaceMethod(invocation);
//获取原始方法
TwoPhaseBusinessAction businessAction = (TwoPhaseBusinessAction)method.getAnnotation(TwoPhaseBusinessAction.class);
//获取标注了注解TwoPhaseBusinessAction的两阶段操作
if (businessAction != null) {
String xid = RootContext.getXID();
RootContext.unbind();
RootContext.bindInterceptorType(xid, BranchType.TCC);
Object var7;
try {
Object[] methodArgs = invocation.getArguments();
ActionInterceptorHandler var10000 = this.actionInterceptorHandler;
invocation.getClass();
Map ret = var10000.proceed(method, methodArgs, xid, businessAction, invocation::proceed);
//执行相关操作,actionInterceptorHandler的proceed()方法
var7 = ret.get("result");
} finally {
RootContext.unbindInterceptorType();
RootContext.bind(xid);
}
return var7;
} else {
return invocation.proceed();
}
}
}
protected Method getActionInterfaceMethod(MethodInvocation invocation) {
protected Class> getProxyInterface(Object proxyBean) throws Exception {
GlobalTransactionalInterceptor:at模式拦截器
public class GlobalTransactionalInterceptor implements ConfigurationChangeListener, MethodInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalTransactionalInterceptor.class);
private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
private final TransactionalTemplate transactionalTemplate = new TransactionalTemplate();
private final GlobalLockTemplate
相关注解
TwoPhaseBusinessAction:tcc模式两阶段操作注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) //注解标注在方法上
@Inherited
public @interface TwoPhaseBusinessAction {
String name();
String commitMethod() default "commit"; //提交方法
String rollbackMethod() default "rollback"; //回滚方法
}
GlobalLock:全局锁
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) //标注在方法上
@Inherited
public @interface GlobalLock {
}
GlobalTransactional:全局事务
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) //标注在方法上
@Inherited
public @interface GlobalTransactional {
int timeoutMills() default 60000;
String name() default "";
Class extends Throwable>[] rollbackFor() default {}; //抛出指定异常回滚
String[] rollbackForClassName() default {};
Class extends Throwable>[] noRollbackFor() default {}; //抛出指定异常不回滚
String[] noRollbackForClassName() default {};
}
数据源自动代理
EnableAutoDataSourceProxy:自动创建代理数据源,该注解seata-spring-boot-starter 1.1.0开始使用
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({AutoDataSourceProxyRegistrar.class})
@Documented
public @interface EnableAutoDataSourceProxy {
boolean useJdkProxy() default false;
}
AutoDataSourceProxyRegistrar:自动数据源代理注册类
public class AutoDataSourceProxyRegistrar implements ImportBeanDefinitionRegistrar {
private static final String ATTRIBUTE_KEY_USE_JDK_PROXY = "useJdkProxy";
public static final String BEAN_NAME_SEATA_DATA_SOURCE_BEAN_POST_PROCESSOR = "seataDataSourceBeanPostProcessor";
public AutoDataSourceProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition("seataDataSourceBeanPostProcessor")) {
boolean useJdkProxy = Boolean.valueOf(importingClassMetadata.getAnnotationAttributes(EnableAutoDataSourceProxy.class.getName()).get("useJdkProxy").toString());
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SeataDataSourceBeanPostProcessor.class).addConstructorArgValue(useJdkProxy).getBeanDefinition();
registry.registerBeanDefinition("seataDataSourceBeanPostProcessor", beanDefinition);
}
}
}
SeataDataSourceBeanPostProcessor:创建代理数据源操作类
public class SeataDataSourceBeanPostProcessor implements BeanPostProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(SeataDataSourceBeanPostProcessor.class);
private final boolean useJdkProxy; //是否使用jdk代理
public SeataDataSourceBeanPostProcessor(boolean useJdkProxy) {
this.useJdkProxy = useJdkProxy;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DataSource && !(bean instanceof DataSourceProxy)) {
//bean是DataSource实例,且不是数据源代理类,则创建代理数据源
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Auto proxy of [{}]", beanName);
}
return this.proxyDataSource(bean);
} else {
return bean; //否则直接返回bean
}
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof DataSourceProxy) {
//自动创建数据源不能和手工创建数据源同时配置,否则报错
throw new ShouldNeverHappenException("Auto proxy of DataSource can't be enabled as you've created a DataSourceProxy bean.Please consider removing DataSourceProxy bean or disabling auto proxy of DataSource.");
} else {
return bean;
}
}
private Object proxyDataSource(Object originBean) { //创建代理数据源
private Object handleMethodProxy(DataSourceProxy dataSourceProxy, Method method, Object[] args, Object originBean) throws InvocationTargetException, IllegalAccessException {
//创建代理数据源的具体操作
事务管理器
TransactionManager:事务管理器接口
public interface TransactionManager {
String begin(String var1, String var2, String var3, int var4) throws TransactionException; //开启全局事务
GlobalStatus commit(String var1) throws TransactionException; //提交全局事务
GlobalStatus rollback(String var1) throws TransactionException;//回滚全局事务
GlobalStatus getStatus(String var1) throws TransactionException; //获取全局事务执行状态
GlobalStatus globalReport(String var1, GlobalStatus var2) throws TransactionException;
//提交全局事务执行状态
}
DefaultTransactionManager:全局事务管理器默认实现类
public class DefaultTransactionManager implements TransactionManager {
public DefaultTransactionManager() {
}
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout) throws TransactionException {
//开启全局事务
GlobalBeginRequest request = new GlobalBeginRequest();
request.setTransactionName(name);
request.setTimeout(timeout);
GlobalBeginResponse response = (GlobalBeginResponse)this.syncCall(request);
if (response.getResultCode() == ResultCode.Failed) {
throw new TmTransactionException(TransactionExceptionCode.BeginFailed, response.getMsg());
} else {
return response.getXid();
}
}
public GlobalStatus commit(String xid) throws TransactionException {
//提交全局事务
GlobalCommitRequest globalCommit = new GlobalCommitRequest();
globalCommit.setXid(xid);
GlobalCommitResponse response = (GlobalCommitResponse)this.syncCall(globalCommit);
return response.getGlobalStatus();
}
public GlobalStatus rollback(String xid) throws TransactionException {
//回滚全局事务
GlobalRollbackRequest globalRollback = new GlobalRollbackRequest();
globalRollback.setXid(xid);
GlobalRollbackResponse response = (GlobalRollbackResponse)this.syncCall(globalRollback);
return response.getGlobalStatus();
}
public GlobalStatus getStatus(String xid) throws TransactionException {
//获取全局事务执行状态
GlobalStatusRequest queryGlobalStatus = new GlobalStatusRequest();
queryGlobalStatus.setXid(xid);
GlobalStatusResponse response = (GlobalStatusResponse)this.syncCall(queryGlobalStatus);
return response.getGlobalStatus();
}
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
//提交全局事务执行状态
GlobalReportRequest globalReport = new GlobalReportRequest();
globalReport.setXid(xid);
globalReport.setGlobalStatus(globalStatus);
GlobalReportResponse response = (GlobalReportResponse)this.syncCall(globalReport);
return response.getGlobalStatus();
}
private AbstractTransactionResponse syncCall(AbstractTransactionRequest request) throws TransactionException {
try {
return (AbstractTransactionResponse)TmRpcClient.getInstance().sendMsgWithResponse(request);
//执行相关事务请求
} catch (TimeoutException var3) {
throw new TmTransactionException(TransactionExceptionCode.IO, "RPC timeout", var3);
}
}
}
资源管理器
ResourceManager:资源管理器接口
public interface ResourceManager extends ResourceManagerInbound, ResourceManagerOutbound {
void registerResource(Resource var1); //注册资源服务器
void unregisterResource(Resource var1); //断开资源服务器
Map getManagedResources();
BranchType getBranchType(); //获取事务模式:at、tcc、saga
}
BranchType:事务模式
public enum BranchType {
AT,
TCC,
SAGA;
private BranchType() {
}
public static BranchType get(byte ordinal) {
public static BranchType get(int ordinal) {
ResourceManagerInBound:提交、回滚本地事务接口
public interface ResourceManagerInbound {
BranchStatus branchCommit(BranchType var1, String var2, long var3, String var5, String var6) throws TransactionException;
//提交分支事务
BranchStatus branchRollback(BranchType var1, String var2, long var3, String var5, String var6) throws TransactionException;
//回滚分支事务
}
ResourcemanagerOutBound:注册、回报之行状态、本地资源锁定接口
public interface ResourceManagerOutbound {
Long branchRegister(BranchType var1, String var2, String var3, String var4, String var5, String var6) throws TransactionException;
//注册本地事务
void branchReport(BranchType var1, String var2, long var3, BranchStatus var5, String var6) throws TransactionException;
//汇报本地事务状态
boolean lockQuery(BranchType var1, String var2, String var3, String var4) throws TransactionException;
//锁定本地相关资源
}
AbstractResourceManager
public abstract class AbstractResourceManager implements ResourceManager {
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractResourceManager.class);
public AbstractResourceManager() {
}
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String applicationData, String lockKeys) throws TransactionException {
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status, String applicationData) throws TransactionException {
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException {
return false;
}
public void unregisterResource(Resource resource) {
throw new NotSupportYetException("unregister a resource");
}
public void registerResource(Resource resource) {
RmRpcClient.getInstance().registerResource(resource.getResourceGroupId(), resource.getResourceId());
}
}
**********************
at 模式资源管理器
DataSourceManager
public class DataSourceManager extends AbstractResourceManager implements Initialize {
private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceManager.class);
private ResourceManagerInbound asyncWorker;
private Map dataSourceCache = new ConcurrentHashMap();
public void setAsyncWorker(ResourceManagerInbound asyncWorker) {
this.asyncWorker = asyncWorker;
}
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException {
try {
GlobalLockQueryRequest request = new GlobalLockQueryRequest();
request.setXid(xid);
request.setLockKey(lockKeys);
request.setResourceId(resourceId);
GlobalLockQueryResponse response = null;
if (RootContext.inGlobalTransaction()) {
response = (GlobalLockQueryResponse)RmRpcClient.getInstance().sendMsgWithResponse(request);
} else {
if (!RootContext.requireGlobalLock()) {
throw new RuntimeException("unknow situation!");
}
response = (GlobalLockQueryResponse)RmRpcClient.getInstance().sendMsgWithResponse(this.loadBalance(), request, (long)NettyClientConfig.getRpcRequestTimeout());
}
if (response.getResultCode() == ResultCode.Failed) {
throw new TransactionException(response.getTransactionExceptionCode(), "Response[" + response.getMsg() + "]");
} else {
return response.isLockable();
}
} catch (TimeoutException var7) {
throw new RmTransactionException(TransactionExceptionCode.IO, "RPC Timeout", var7);
} catch (RuntimeException var8) {
throw new RmTransactionException(TransactionExceptionCode.LockableCheckFailed, "Runtime", var8);
}
}
private String loadBalance() {
InetSocketAddress address = null;
try {
List inetSocketAddressList = RegistryFactory.getInstance().lookup(TmRpcClient.getInstance().getTransactionServiceGroup());
address = (InetSocketAddress)LoadBalanceFactory.getInstance().select(inetSocketAddressList);
} catch (Exception var3) {
LOGGER.error(var3.getMessage());
}
if (address == null) {
throw new FrameworkException(FrameworkErrorCode.NoAvailableService);
} else {
return NetUtil.toStringAddress(address);
}
}
public synchronized void initAsyncWorker(ResourceManagerInbound asyncWorker) {
this.setAsyncWorker(asyncWorker);
}
public DataSourceManager() {
}
public void init() {
AsyncWorker asyncWorker = new AsyncWorker();
asyncWorker.init();
this.initAsyncWorker(asyncWorker);
}
public void registerResource(Resource resource) {
DataSourceProxy dataSourceProxy = (DataSourceProxy)resource; //注册代理数据源
this.dataSourceCache.put(dataSourceProxy.getResourceId(), dataSourceProxy);
super.registerResource(dataSourceProxy);
}
public void unregisterResource(Resource resource) {
throw new NotSupportYetException("unregister a resource");
}
public DataSourceProxy get(String resourceId) {
return (DataSourceProxy)this.dataSourceCache.get(resourceId);
}
public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
return this.asyncWorker.branchCommit(branchType, xid, branchId, resourceId, applicationData);
}
public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
DataSourceProxy dataSourceProxy = this.get(resourceId);
if (dataSourceProxy == null) {
throw new ShouldNeverHappenException();
} else {
try {
UndoLogManagerFactory.getUndoLogManager(dataSourceProxy.getDbType()).undo(dataSourceProxy, xid, branchId);
} catch (TransactionException var9) {
StackTraceLogger.info(LOGGER, var9, "[stacktrace]branchRollback failed. branchType:[{}], xid:[{}], branchId:[{}], resourceId:[{}], applicationData:[{}]. stacktrace:[{}]", new Object[]{branchType, xid, branchId, resourceId, applicationData, var9.getMessage()}, "branchRollback failed reason [{}]", new Object[]{var9.getMessage()});
if (var9.getCode() == TransactionExceptionCode.BranchRollbackFailed_Unretriable) {
return BranchStatus.PhaseTwo_RollbackFailed_Unretryable;
}
return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
}
return BranchStatus.PhaseTwo_Rollbacked;
}
}
public Map getManagedResources() {
return this.dataSourceCache;
}
public BranchType getBranchType() {
return BranchType.AT;
}
}
DataSourceProxy:数据源代理
public class DataSourceProxy extends AbstractDataSourceProxy implements Resource {
private String resourceGroupId;
private static final String DEFAULT_RESOURCE_GROUP_ID = "DEFAULT";
private String jdbcUrl;
private String dbType;
private static boolean ENABLE_TABLE_META_CHECKER_ENABLE = ConfigurationFactory.getInstance().getBoolean("client.rm.tableMetaCheckEnable", false);
private static final long TABLE_META_CHECKER_INTERVAL = 60000L;
private final ScheduledExecutorService tableMetaExcutor;
public DataSourceProxy(DataSource targetDataSource) {
this(targetDataSource, "DEFAULT");
}
public DataSourceProxy(DataSource targetDataSource, String resourceGroupId) {
super(targetDataSource);
this.tableMetaExcutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("tableMetaChecker", 1, true));
this.init(targetDataSource, resourceGroupId);
}
private void init(DataSource dataSource, String resourceGroupId) { //相关初始化操作
public Connection getPlainConnection() throws SQLException {
public String getDbType() {
return this.dbType;
}
public ConnectionProxy getConnection() throws SQLException { //获取代理连接
Connection targetConnection = this.targetDataSource.getConnection();
return new ConnectionProxy(this, targetConnection);
}
public ConnectionProxy getConnection(String username, String password) throws SQLException {
//使用用户名、密码获取代理连接
Connection targetConnection = this.targetDataSource.getConnection(username, password);
return new ConnectionProxy(this, targetConnection);
}
public String getResourceGroupId() {
public String getResourceId() {
public BranchType getBranchType() {
return BranchType.AT;
}
}
ConnectionProxy:连接代理
public class ConnectionProxy extends AbstractConnectionProxy {
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionProxy.class);
private ConnectionContext context = new ConnectionContext();
private static final int REPORT_RETRY_COUNT = ConfigurationFactory.getInstance().getInt("client.rm.reportRetryCount", 5);
public static final boolean IS_REPORT_SUCCESS_ENABLE = ConfigurationFactory.getInstance().getBoolean("client.rm.reportSuccessEnable", false);
private static final ConnectionProxy.LockRetryPolicy LOCK_RETRY_POLICY = new ConnectionProxy.LockRetryPolicy();
public ConnectionProxy(DataSourceProxy dataSourceProxy, Connection targetConnection) {
****************
普通方法
public ConnectionContext getContext() {
public void bind(String xid) {
public void setGlobalLockRequire(boolean isLock) { //全局锁相关操作
public boolean isGlobalLockRequire() {
public void checkLock(String lockKeys) throws SQLException {
public boolean lockQuery(String lockKeys) throws SQLException {
private void recognizeLockKeyConflictException(TransactionException te) throws SQLException {
private void recognizeLockKeyConflictException(TransactionException te, String lockKeys) throws SQLException {
public void appendUndoLog(SQLUndoLog sqlUndoLog) { //undo日志
public void appendLockKey(String lockKey) { //全局锁
public void commit() throws SQLException {
private void doCommit() throws SQLException {
private void processLocalCommitWithGlobalLocks() throws SQLException {
private void processGlobalTransactionCommit() throws SQLException {
private void register() throws TransactionException {
public void rollback() throws SQLException {
public void setAutoCommit(boolean autoCommit) throws SQLException {
private void report(boolean commitDone) throws SQLException {
AbstarctConnectionProxy
public abstract class AbstractConnectionProxy implements Connection {
protected DataSourceProxy dataSourceProxy;
protected Connection targetConnection;
public AbstractConnectionProxy(DataSourceProxy dataSourceProxy, Connection targetConnection) {
**************
部分方法
public Statement createStatement() throws SQLException {
Statement targetStatement = this.getTargetConnection().createStatement();
return new StatementProxy(this, targetStatement);
}//创建statement代理
public PreparedStatement prepareStatement(String sql) throws SQLException {
String dbType = this.getDbType();
PreparedStatement targetPreparedStatement = null;
if (RootContext.inGlobalTransaction()) {
SQLRecognizer sqlRecognizer = SQLVisitorFactory.get(sql, dbType);
if (sqlRecognizer != null && sqlRecognizer.getSQLType() == SQLType.INSERT) {
String tableName = ColumnUtils.delEscape(sqlRecognizer.getTableName(), dbType);
TableMeta tableMeta = TableMetaCacheFactory.getTableMetaCache(dbType).getTableMeta(this.getTargetConnection(), tableName, this.getDataSourceProxy().getResourceId());
targetPreparedStatement = this.getTargetConnection().prepareStatement(sql, new String[]{tableMeta.getPkName()});
}
}
if (targetPreparedStatement == null) {
targetPreparedStatement = this.getTargetConnection().prepareStatement(sql);
}
return new PreparedStatementProxy(this, targetPreparedStatement, sql);
}//创建preparedStatementProxy代理
StatementProxy:使用ExecuteTemplate执行sql语句
public class StatementProxy extends AbstractStatementProxy {
public StatementProxy(AbstractConnectionProxy connectionWrapper, T targetStatement, String targetSQL) throws SQLException {
super(connectionWrapper, targetStatement, targetSQL);
}
public StatementProxy(AbstractConnectionProxy connectionWrapper, T targetStatement) throws SQLException {
this(connectionWrapper, targetStatement, (String)null);
}
public ConnectionProxy getConnectionProxy() {
return (ConnectionProxy)super.getConnectionProxy();
}
public ResultSet executeQuery(String sql) throws SQLException {
this.targetSQL = sql;
return (ResultSet)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeQuery((String)args[0]);
}, new Object[]{sql});
}
public int executeUpdate(String sql) throws SQLException {
this.targetSQL = sql;
return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeUpdate((String)args[0]);
}, new Object[]{sql});
}
public boolean execute(String sql) throws SQLException {
this.targetSQL = sql;
return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.execute((String)args[0]);
}, new Object[]{sql});
}
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
this.targetSQL = sql;
return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeUpdate((String)args[0], (Integer)args[1]);
}, new Object[]{sql, autoGeneratedKeys});
}
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
this.targetSQL = sql;
return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeUpdate((String)args[0], (int[])((int[])args[1]));
}, new Object[]{sql, columnIndexes});
}
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
this.targetSQL = sql;
return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeUpdate((String)args[0], (String[])((String[])args[1]));
}, new Object[]{sql, columnNames});
}
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
this.targetSQL = sql;
return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.execute((String)args[0], (Integer)args[1]);
}, new Object[]{sql, autoGeneratedKeys});
}
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
this.targetSQL = sql;
return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.execute((String)args[0], (int[])((int[])args[1]));
}, new Object[]{sql, columnIndexes});
}
public boolean execute(String sql, String[] columnNames) throws SQLException {
this.targetSQL = sql;
return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
return statement.execute((String)args[0], (String[])((String[])args[1]));
}, new Object[]{sql, columnNames});
}
public int[] executeBatch() throws SQLException {
return (int[])ExecuteTemplate.execute(this, (statement, args) -> {
return statement.executeBatch();
}, new Object[0]);
}
}
PreparedStatementProxy:预编译语句代理,使用ExecuteTemplate执行sql语句
public class PreparedStatementProxy extends AbstractPreparedStatementProxy implements PreparedStatement, ParametersHolder {
public ArrayList
ExecuteTemplate:执行sql语句,并做事务处理
public class ExecuteTemplate {
public ExecuteTemplate() {
}
public static T execute(StatementProxy statementProxy, StatementCallback statementCallback, Object... args) throws SQLException {
return execute((SQLRecognizer)null, statementProxy, statementCallback, args);
}
public static T execute(SQLRecognizer sqlRecognizer, StatementProxy statementProxy, StatementCallback statementCallback, Object... args) throws SQLException {
if (!RootContext.inGlobalTransaction() && !RootContext.requireGlobalLock()) {
return statementCallback.execute(statementProxy.getTargetStatement(), args);
} else {
if (sqlRecognizer == null) {
sqlRecognizer = SQLVisitorFactory.get(statementProxy.getTargetSQL(), statementProxy.getConnectionProxy().getDbType());
}
Object executor;
if (sqlRecognizer == null) {
executor = new PlainExecutor(statementProxy, statementCallback);
} else {
switch(sqlRecognizer.getSQLType()) {
case INSERT:
executor = new InsertExecutor(statementProxy, statementCallback, sqlRecognizer);
break;
case UPDATE:
executor = new UpdateExecutor(statementProxy, statementCallback, sqlRecognizer);
break;
case DELETE:
executor = new DeleteExecutor(statementProxy, statementCallback, sqlRecognizer);
break;
case SELECT_FOR_UPDATE:
executor = new SelectForUpdateExecutor(statementProxy, statementCallback, sqlRecognizer);
break;
default:
executor = new PlainExecutor(statementProxy, statementCallback);
}
}
try {
T rs = ((Executor)executor).execute(args);
return rs;
} catch (Throwable var7) {
Throwable ex = var7;
if (!(var7 instanceof SQLException)) {
ex = new SQLException(var7);
}
throw (SQLException)ex;
}
}
}
}
**********************
tcc 模式资源管理器
TccResourceManager
public class TCCResourceManager extends AbstractResourceManager {
private Map tccResourceCache = new ConcurrentHashMap();
public TCCResourceManager() {
}
public void registerResource(Resource resource) {
TCCResource tccResource = (TCCResource)resource;
this.tccResourceCache.put(tccResource.getResourceId(), tccResource);
super.registerResource(tccResource);
}
public Map getManagedResources() {
return this.tccResourceCache;
}
public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
TCCResource tccResource = (TCCResource)this.tccResourceCache.get(resourceId);
if (tccResource == null) { //没有tccResource,直接抛出异常
throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
} else {
Object targetTCCBean = tccResource.getTargetBean(); //获取目标对象
Method commitMethod = tccResource.getCommitMethod(); //获取对应的commit方法
if (targetTCCBean != null && commitMethod != null) {
try {
boolean result = false;
BusinessActionContext businessActionContext = this.getBusinessActionContext(xid, branchId, resourceId, applicationData);
Object ret = commitMethod.invoke(targetTCCBean, businessActionContext); //执行commit方法
LOGGER.info("TCC resource commit result : {}, xid: {}, branchId: {}, resourceId: {}", new Object[]{ret, xid, branchId, resourceId});
if (ret != null) {
if (ret instanceof TwoPhaseResult) {
result = ((TwoPhaseResult)ret).isSuccess();
} else {
result = (Boolean)ret;
}
}
return result ? BranchStatus.PhaseTwo_Committed : BranchStatus.PhaseTwo_CommitFailed_Retryable; //根据执行结果返回二阶段提交或者二阶段回滚
} catch (Throwable var13) {
String msg = String.format("commit TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
LOGGER.error(msg, var13);
throw new FrameworkException(var13, msg);
}
} else {
throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
}
}
}
public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
TCCResource tccResource = (TCCResource)this.tccResourceCache.get(resourceId);
if (tccResource == null) { //没有tcc资源则抛出异常
throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
} else {
Object targetTCCBean = tccResource.getTargetBean(); //获取目标对象
Method rollbackMethod = tccResource.getRollbackMethod();//获取回滚方法
if (targetTCCBean != null && rollbackMethod != null) {
try {
boolean result = false;
BusinessActionContext businessActionContext = this.getBusinessActionContext(xid, branchId, resourceId, applicationData);
Object ret = rollbackMethod.invoke(targetTCCBean, businessActionContext); //执行回滚方法
LOGGER.info("TCC resource rollback result : {}, xid: {}, branchId: {}, resourceId: {}", new Object[]{ret, xid, branchId, resourceId});
if (ret != null) {
if (ret instanceof TwoPhaseResult) {
result = ((TwoPhaseResult)ret).isSuccess();
} else {
result = (Boolean)ret;
}
}
return result ? BranchStatus.PhaseTwo_Rollbacked : BranchStatus.PhaseTwo_RollbackFailed_Retryable; //根据执行结果返回已回滚、或者回滚失败进行重试
} catch (Throwable var13) {
String msg = String.format("rollback TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
LOGGER.error(msg, var13);
throw new FrameworkException(var13, msg);
}
} else {
throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
}
}
}
protected BusinessActionContext getBusinessActionContext(String xid, long branchId, String resourceId, String applicationData) {
Map tccContext = StringUtils.isBlank(applicationData) ? new HashMap() : (Map)JSON.parse(applicationData);
Map actionContextMap = (Map)((Map)tccContext).get("actionContext");
BusinessActionContext businessActionContext = new BusinessActionContext(xid, String.valueOf(branchId), actionContextMap);
businessActionContext.setActionName(resourceId);
return businessActionContext;
}
public BranchType getBranchType() {
return BranchType.TCC;
}
}