CREATE TABLE `test_aop` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
@Component @Slf4j public class AopDataService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private AopDataService aopDataService; // 写入数据 @Transactional public void insert(String value) { jdbcTemplate.update("insert into test_aop(name) values(‘" + value + "‘)"); } // 写入数据后抛异常 @Transactional public void insertAndRollback(String value) { log.info("insertAndRollback {}", value); jdbcTemplate.update("insert into test_aop(name) values(‘" + value + "‘)"); throw new RuntimeException(); } // 使用this调用事务方法 public void invokeMethod() { try { this.insertAndRollback("invokeMethod"); // 这里的this就是AopDataService,不是代理对象。 // 所以调用的insertAndRollback方式是原生方法,不是@Transactional注解代理后的对象 } catch (RuntimeException ex) { log.warn("Catch an Exception in invokeMethod()"); } } // 使用this.aopDataService调用事务方法 public void invokeMethodAutowired() { try { this.aopDataService.insertAndRollback("invokeMethodAutowired"); // this.aopDataService 代理对象,事务生效 } catch (RuntimeException ex) { log.error("Catch an Exception in invokeMethodAutowired()"); } } // 使用getBean调用事务方法 public void invokeMethodGetBean() { try { AopDataService aopDataService = SpringUtil.getBean("aopDataService", AopDataService.class); aopDataService.insertAndRollback("invokeMethodGetBean"); // aopDataService 代理对象,事务生效 } catch (RuntimeException ex) { log.warn("Catch an Exception in invokeMethodGetBean()"); } } }
@Autowired private AopDataService aopDataService; // 写入成功(this.aopDataService是代理对象) @Test public void insert() { this.aopDataService.insert("insert"); } // 抛异常,数据写入不成功(this.aopDataService是代理对象) @Test public void insertAndRollback() { this.aopDataService.insertAndRollback("insertAndRollback"); } // 抛异常,数据写入成功(invokeMethod方法内未使用AopDataService代理对象) @Test public void invokeMethod() { this.aopDataService.invokeMethod(); } // 抛异常,数据写入不成功(invokeMethodAutowired方法内使用了AopDataService代理对象) @Test public void invokeMethodAutowired() { this.aopDataService.invokeMethodAutowired(); } // 抛异常,数据写入不成功(invokeMethodGetBean方法内使用了AopDataService代理对象) @Test public void invokeMethodGetBean() { this.aopDataService.invokeMethodGetBean(); }
这里的this就是 AopDataService,不是代理对象。
所以调用的insertAndRollback方式是原生方法,不是@Transactional注解代理后的对象
原文:https://www.cnblogs.com/gossip/p/14280772.html