二、GlobalTransactionalInterceptor拦截器
所有文章
https://www.cnblogs.com/lay2017/p/12485081.html
正文
在上一篇文章中,我们看到被@GlobalTransactional或者@GlobalLock注解的方法,该Bean会做AOP事务增强。
本文将阅读关于@GlobalTransactional的事务增强拦截器GlobalTransactionalInterceptor。首先,我们看一下它的UML类图
GlobalTransactionalInterceptor设计路线只有两条,一条是spring aop的方法拦截器,另一条是seata的配置变更监听器。监听器无非就是当配置变化的时候做回调处理,GlobalTransactionalInterceptor主要是监听全局事务的关闭。
那么,我们关注点放在对MethodInterceptor的实现上,跟进invoke方法的实现
拦截器invoke方法
@Override 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); final Method method = BridgeMethodResolver.findBridgedMethod(specificMethod); // 拿到@GlobalTransactional注解的元数据 final GlobalTransactional globalTransactionalAnnotation = getAnnotation(method, GlobalTransactional.class); // 拿到@GlobalLock注解的元数据 final GlobalLock globalLockAnnotation = getAnnotation(method, GlobalLock.class); // 处理@GlobalTransactional if (!disable && globalTransactionalAnnotation != null) { return handleGlobalTransaction(methodInvocation, globalTransactionalAnnotation); // 处理@GlobalLock } else if (!disable && globalLockAnnotation != null) { return handleGlobalLock(methodInvocation); // 直接调用原始方法 } else { return methodInvocation.proceed(); } }
如果事务是开启的 disable=false,那么判断方法是否有@GlobalTransactional或者@GlobalLock注解。如果有的话,那么执行对应的处理方法。如果没有,那么直接执行proceed。
handleGlobalTransaction
handleGlobalTransaction处理@GlobalTransactional注解,跟进该方法
private Object handleGlobalTransaction(final MethodInvocation methodInvocation, final GlobalTransactional globalTrxAnno) throws Throwable { try { // 事务执行模板 return transactionalTemplate.execute(new TransactionalExecutor() { @Override public Object execute() throws Throwable { // 执行原始方法 return methodInvocation.proceed(); } public String name() { // 自定义或者格式化生成事务的名称 String name = globalTrxAnno.name(); if (!StringUtils.isNullOrEmpty(name)) { return name; } return formatMethod(methodInvocation.getMethod()); } @Override public TransactionInfo getTransactionInfo() { // 将注解包装成TransactionInfo对象 TransactionInfo transactionInfo = new TransactionInfo(); transactionInfo.setTimeOut(globalTrxAnno.timeoutMills()); transactionInfo.setName(name()); 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) { // 执行异常 TransactionalExecutor.Code code = e.getCode(); switch (code) { case RollbackDone: throw e.getOriginalException(); case BeginFailure: failureHandler.onBeginFailure(e.getTransaction(), e.getCause()); throw e.getCause(); case CommitFailure: failureHandler.onCommitFailure(e.getTransaction(), e.getCause()); throw e.getCause(); case RollbackFailure: failureHandler.onRollbackFailure(e.getTransaction(), e.getCause()); throw e.getCause(); default: throw new ShouldNeverHappenException("Unknown TransactionalExecutor.Code: " + code); } } }
可以看到拦截器把处理@GlobalTransactional的主体执行逻辑委托给了TransactionalTemplate这个模板的execute方法,而TransactionalExecutor执行器只是提供了执行原始方法,@GlobalTransactional元数据信息,事务名称的实现。
handleGlobalLock
handleGlobalLock处理的是@GlobalLock的主体逻辑,比起TransactionalTemplate简单了很多。
单纯地把所有逻辑交给GlobalLockTemplate的execute方法,执行器只是负责执行原始方法
private Object handleGlobalLock(final MethodInvocation methodInvocation) throws Exception { return globalLockTemplate.execute(() -> { try { // 执行原始方法 return methodInvocation.proceed(); } catch (Throwable e) { if (e instanceof Exception) { throw (Exception)e; } else { throw new RuntimeException(e); } } }); }
总结
GlobalTransactionalInterceptor拦截器逻辑比较简单,基本上都委托给了TransactionalTemplate和GlobalLockTemplate。拦截器只负责把对应的注解逻辑分发给对应的逻辑模板来处理。