动态代理和@transactional事务传递简单理解

  • Post author:
  • Post category:其他


动态代理简述:有两种实现方式,一是jdk反射机制代理,二是CGLIB增强代理。

这里只简述jdk反射机制的使用步骤:新建接口,新建接口的实现类,并编写具体实现内容,新建处理器类实现InvocationHandler,实现invoke方法,可以在其中写切面内容。然后使用时,调用Proxy.newProxyInstance方法,三个参数分别是,要代理的目标类的加载器,目标类实现的所有接口,处理器类。最后调用切点方法。

spring使用@Transactional事务传递时,假如说controller调用service中的方法A,注意这个调用过程是通过前面说的处理器调用的,a没有@Transactional这个注解,那么在走这个处理器的时候会先判断是否有这个注解,如果没有就不会走这个切点的切面方法,所以也就不会开启事务。接着在a方法里面有调用b方法,b方法有@Transactional注解,但是这个调用属于方法间的调用,不走代理,所以此时的注解并没有起作用,也就不会开启事务。

如果控制层直接调用service的b方法,那么是可以事务的。

如果先调用b方法,再调用a方法,无论a是否带@transactional注解,都会在b的事务中。因为了解aop的都知道,方法的实体是在前置后置之间执行的就如同事务前后的开启和关闭。

为什么呢?因为service层注入到控制层,对象是交给spring容器管理的,这就涉及到了spring三级缓存了,三级缓存中第三级存放的是aop代理对象。当控制层调用注入到自己类中的业务层方法时,是通过代理的,而在这个代理过程中,会有一个判断,判断该方法是否有@transactional注解,有就走带事务的语句,没有就直接执行sql.

解决办法,明白原理了,那么解决办法就是

1:把注解加到整个类上,这样就保证了任何一个方法都是通过代理调用的。

2在当前类中注入当前类,然后.方法去调用。或者是把方法放到别的bean中,注入进来,再.方法调用。

注解的作用:比如这里的@transactional注解作用就是通过所在方法是否有这个注解来判断的。如果这个注解中有方法就扩大了判断范围,比如@transactional提供的七个事务传递参数,也是通过判断走对应流程的



版权声明:本文为csdnliuxin123524原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。