理解spring事务底层原理

事务是一种all or nothing的执行策略,常见数据库,这种策略遵从ACID原则,可以很好的保证业务的执行,spring事务底层可以使用tx命名空间实现,也可以通过Transactional注解的方式来实现,本文就讲下spring transactional注解底层的工作原理,要了解这个工作原理,首先要了解cglib的工作原理,这个可以参考文章:https://blog.csdn.net/john1337/article/details/88762825

了解了cglib的基本工作原理后,spring transactional底层工作原理就很容易理解了,笔者就把这个运作原理涉及到的几个重要的相关类在这里列举出来,感兴趣的进行代码跟踪即可了解:

DefaultAdvisorAutoProxyCreator  这是BeanPostProcessor,重要的其基类AbstractAdvisorAutoProxyCreatorpostProcessAfterInitialization方法,这个方法内部生成了对应service的代理类,基本代理类代码类似下面:

   private boolean CGLIB$BOUND;
   public static Object CGLIB$FACTORY_DATA;
   private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
   private static final Callback[] CGLIB$STATIC_CALLBACKS;
   private MethodInterceptor CGLIB$CALLBACK_0;
   private MethodInterceptor CGLIB$CALLBACK_1;
   private NoOp CGLIB$CALLBACK_2;
   private Dispatcher CGLIB$CALLBACK_3;
   private Dispatcher CGLIB$CALLBACK_4;
   private MethodInterceptor CGLIB$CALLBACK_5;
   private MethodInterceptor CGLIB$CALLBACK_6;
   private static Object CGLIB$CALLBACK_FILTER;
   private static final Method CGLIB$insert$0$Method;
   private static final MethodProxy CGLIB$insert$0$Proxy;
   private static final Object[] CGLIB$emptyArgs;
   private static final Method CGLIB$selectByPrimaryKey$1$Method;
   private static final MethodProxy CGLIB$selectByPrimaryKey$1$Proxy;
   private static final Method CGLIB$updateByPrimaryKeySelective$2$Method;
   private static final MethodProxy CGLIB$updateByPrimaryKeySelective$2$Proxy;
   private static final Method CGLIB$updateByPrimaryKey$3$Method;
   private static final MethodProxy CGLIB$updateByPrimaryKey$3$Proxy;
   private static final Method CGLIB$insertSelective$4$Method;
   private static final MethodProxy CGLIB$insertSelective$4$Proxy;
   private static final Method CGLIB$deleteByPrimaryKey$5$Method;
   private static final MethodProxy CGLIB$deleteByPrimaryKey$5$Proxy;
   private static final Method CGLIB$equals$6$Method;
   private static final MethodProxy CGLIB$equals$6$Proxy;
   private static final Method CGLIB$toString$7$Method;
   private static final MethodProxy CGLIB$toString$7$Proxy;
   private static final Method CGLIB$hashCode$8$Method;
   private static final MethodProxy CGLIB$hashCode$8$Proxy;
   private static final Method CGLIB$clone$9$Method;
   private static final MethodProxy CGLIB$clone$9$Proxy;

   static void CGLIB$STATICHOOK249() {
      CGLIB$THREAD_CALLBACKS = new ThreadLocal();
      CGLIB$emptyArgs = new Object[0];
      Class var0 = Class.forName("hello.service.bank.impl.SubBankServiceImpl$$EnhancerBySpringCGLIB$$8fea4d01");
      Class var1;
      Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
      CGLIB$equals$6$Method = var10000[0];
      CGLIB$equals$6$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$6");
      CGLIB$toString$7$Method = var10000[1];
      CGLIB$toString$7$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$7");
      CGLIB$hashCode$8$Method = var10000[2];
      CGLIB$hashCode$8$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$8");
      CGLIB$clone$9$Method = var10000[3];
      CGLIB$clone$9$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$9");
      var10000 = ReflectUtils.findMethods(new String[]{"insert", "(Lhello/entity/bank/SubBank;)I", "selectByPrimaryKey", "(Ljava/lang/String;)Lhello/entity/bank/SubBank;", "updateByPrimaryKeySelective", "(Lhello/entity/bank/SubBank;)I", "updateByPrimaryKey", "(Lhello/entity/bank/SubBank;)I", "insertSelective", "(Lhello/entity/bank/SubBank;)I", "deleteByPrimaryKey", "(Ljava/lang/String;)I"}, (var1 = Class.forName("hello.service.bank.impl.SubBankServiceImpl")).getDeclaredMethods());
      CGLIB$insert$0$Method = var10000[0];
      CGLIB$insert$0$Proxy = MethodProxy.create(var1, var0, "(Lhello/entity/bank/SubBank;)I", "insert", "CGLIB$insert$0");
      CGLIB$selectByPrimaryKey$1$Method = var10000[1];
      CGLIB$selectByPrimaryKey$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)Lhello/entity/bank/SubBank;", "selectByPrimaryKey", "CGLIB$selectByPrimaryKey$1");
      CGLIB$updateByPrimaryKeySelective$2$Method = var10000[2];
      CGLIB$updateByPrimaryKeySelective$2$Proxy = MethodProxy.create(var1, var0, "(Lhello/entity/bank/SubBank;)I", "updateByPrimaryKeySelective", "CGLIB$updateByPrimaryKeySelective$2");
      CGLIB$updateByPrimaryKey$3$Method = var10000[3];
      CGLIB$updateByPrimaryKey$3$Proxy = MethodProxy.create(var1, var0, "(Lhello/entity/bank/SubBank;)I", "updateByPrimaryKey", "CGLIB$updateByPrimaryKey$3");
      CGLIB$insertSelective$4$Method = var10000[4];
      CGLIB$insertSelective$4$Proxy = MethodProxy.create(var1, var0, "(Lhello/entity/bank/SubBank;)I", "insertSelective", "CGLIB$insertSelective$4");
      CGLIB$deleteByPrimaryKey$5$Method = var10000[5];
      CGLIB$deleteByPrimaryKey$5$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)I", "deleteByPrimaryKey", "CGLIB$deleteByPrimaryKey$5");
   }

   final int CGLIB$insert$0(SubBank var1) {
      return super.insert(var1);
   }

   public final int insert(SubBank var1) {
      try {
         MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
         if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
         }

         if (var10000 != null) {
            Object var4 = var10000.intercept(this, CGLIB$insert$0$Method, new Object[]{var1}, CGLIB$insert$0$Proxy);
            return var4 == null ? 0 : ((Number)var4).intValue();
         } else {
            return super.insert(var1);
         }
      } catch (Error | RuntimeException var2) {
         throw var2;
      } catch (Throwable var3) {
         throw new UndeclaredThrowableException(var3);
      }
   }

这个就是cglib产生的代理类

CglibAopProxy  这个类getProxy创建了对应的cglib代理

 

DynamicAdvisedInterceptor  这个类实现了MethodInteceptor接口,每次Service调用接口时首先进入的就是DynamicAdvisedInterceptor这个类的intercept方法,该方法内部会判断每个要执行的方法是否有对应的advice,被Transactional注解的方法对应的默认advice就是TransactionInteceptor

TransactionInterceptor 事务增强类,重要的是invoke方法:

    @Override
    public Object invoke(final MethodInvocation invocation) throws Throwable {
        // Work out the target class: may be {@code null}.
        // The TransactionAttributeSource should be passed the target class
        // as well as the method, which may be from an interface.
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

        // Adapt to TransactionAspectSupport's invokeWithinTransaction...
        return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
            @Override
            public Object proceedWithInvocation() throws Throwable {
                return invocation.proceed();
            }
        });
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值