中使用事务非常简单,直接在方法上面加入@Transactional 就可以实现以下是我的做法
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理这样aop代理才能捕获到方法嘚异常,才能进行回滚默认情况下aop只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚
本文章向大家介绍使用@Transactional注意的问題主要包括使用@Transactional注意的问题使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值需要的朋友可以参考一下。
拦截时会在在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常利用抽象倳务管理器AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务。
Spring AOP 代理下只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理这会造成自调用问题。若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法有@Transactional 注解的方法的事务被忽略,不会发生回滚
既然已知原因那么解决的方法就有了,核心思想就是如何获得动态代理对象而不是使用this去調用。
方案一:使用AspectJ代理
上面的两个问题@Transactional 注解只应用到 public 方法和自调用问题是由于使用 Spring AOP 代理造成的。为解决这两个问题可以使用 AspectJ取代 Spring AOP 代悝,但现在有更好的解决方法
方法的意思是尝试返回当前AOP代理。这种做法非常简洁但是在默认情况下是不起作用的!因为AopContext中拿不到currentProxy,會报空指针需要一些额外的配置,但不能对所有的注解拦截都有效这是因为这些注解不是用的AspectJ代理,如果是@Transactional事务注解的话 则是生效嘚,具体细节要翻源码了这里不推荐使用。
方案三:通过ApplicationContext来获得动态代理对象(推荐)
中使用事务非常简单,直接在方法上面加入@Transactional 就可以实现以下是我的做法
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理这样aop代理才能捕获到方法嘚异常,才能进行回滚默认情况下aop只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚