面试官:怎么使用?
答:配置参数:<tx:annotation:driven transaction>,然后直接在方法配置;
面试官:有如下代码场景,A类的a1方法没有标注@Transactional注解,a2方法标注了@Transactional注解,那么在a1方法里调用a2方法,此时会开始事务吗?
答:不会开启事务。
面试官:解释一下为什么?
小小白:a1方法是目标类A的原生方法,调用a1的时候即直接进入目标类A进行调用,在目标类A里面只有a2的原生方法,在a1里调用a2,即直接执行a2的原生方法,并不通过创建代理对象进行调用,所以并不会进入TransactionInterceptor的invoke方法,不会开启事务。
面试官:那此时如果在a1方法上标注@Transactional注解,a2方法不标注@Transactional注解,但是a1方法的访问修饰符是protected,在a1方法里调用a2方法会开始事务吗?
答:也不会开启事务。
面试官:根据你上面的回答改了代码,为什么还是不会开启事务?
答:@Transactional的工作机制是基于AOP实现的,而AOP是使用动态代理实现的,动态代理要么是JDK方式、要么是Cglib方式。如果是JDK动态代理的方式,根据上面的分析可以知道,目标类的目标方法是在接口中定义的,也就是必须是public修饰的方法才可以被代理。如果是Cglib方式,代理类是目标类的子类,理论上可以代理public和protected方法,但是Spring在进行事务增强是否能够应用到当前目标类判断的时候,遍历的是目标类的public方法,所以Cglib方式也只对public方法有效。