先看代码
package com.benx.data; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service("personService1") public class PersonServiceImpl1 implements PersonService { @Resource private PersonDao personDao; @Resource(name = "personService1") PersonService personService1; @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.NOT_SUPPORTED) public void test() { personService1.test1(); test2(); personService1.test3(); } @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW) public void test1() { personDao.insert(101, "nam101"); } @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public void test2() { personDao.insert(102, "nam102"); } @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public void test3() { personDao.insert(103, "nam103"); } @Override @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public void test4() { personDao.insert(104, "nam104"); } }
测试代码
package com.benx.data; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("com/benx/data/spring-data.xml"); PersonService service1 = (PersonService) context.getBean("personService1"); service1.test(); } }
在 PersonServiceImpl1.test方法中有
personService1.test1(); 和 this.test2(); 方法调用,且test1和test2都有@Transactional配置,但是使用personService1.test1()的事务会生效但是this.test()的事务无效,原因是前者会使用到代理但是后者没有。
那么为什么一个使用代理一个没有呢? Spring对于接口的代理默认使用JdkDynamicAopProxy,该类实现InvocationHandler,当调用方法时实际会执行该类的invoke方法,invoke方法会执行拦截方法和target.method方法执行;最后结论就是:
personService1.test1(); 相当于JdkDynamicAopProxy.invoke(); invoke内部会执行拦截功能和执行target.test1
this.test2();相当于target.test();