600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Spring事务注解@Transactional失效和切面失效问题

Spring事务注解@Transactional失效和切面失效问题

时间:2023-04-19 08:42:04

相关推荐

Spring事务注解@Transactional失效和切面失效问题

人最宝贵的是生命,生命属于人只有一次。人的一生应当这样度过:当他回首往事时,不会因虚度年华而悔恨,也不会因碌碌无为而羞耻。这样,临终前他就可以自豪地说:“我已经把自己整个生命和全部精力都献给了世界上最壮丽的事业——为人类的解放而奋斗。”——《钢铁是怎样炼成的》

1、引言

最近在开发采用Spring框架的项目中,在A方法上使用了@Transactional注解,但当在同一个类的B方法中调用A方法,发现A发生异常不回滚,A方法的事务注解失效了。

public class TestTransactional {@Transactional(propagation = Propagation.REQUIRED)public void A() {User user = new User("chunsoft");userMapper.insertSelective(user);if (true) {throw new RuntimeException("抛异常");}}public void B() {this.A();}}

为什么会出现这样的问题呢,我们需要研究下,@Transactional注解的本质:Spring之所以可以对开启@Transactional的方法进行事务管理,是因为Spring为当前类生成了一个代理类,然后在执行相关方法时,会判断这个方法有没有@Transactional注解,如果有的话,则会开启一个事务。 但是,上面这种调用方式时,在调用B()时,使用的并不是代理对象,从而导致this.A()时也不是代理对象,从而导致@Transactional失败。

2、解决方案

(1)首先获取到代理类,再调用事务方法,强行经过代理类,激活事务切面。如:((TestTransactional)AopContext.currentProxy()).A();

(2)通过ApplicationContext上下文获取类的Bean对象。通过类去调用。激活事务切面。

获取上下文工具类:

@Componentpublic class BeanUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {applicationContext = context;}/*** 获取applicationContext*/public static ApplicationContext getApplicationContext() {return applicationContext;}/*** 通过class获取Bean** @param clazz* @param <T>* @return*/public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}}

调用方法:

TestTransactional testTransactional = BeanUtil.getBean(TestTransactional.class);testTransactional.A();

由于事务的实现原理是切面,因此我们在遇到切面相关的失效问题,比如自定义注解等因为方法未通过代理类调用的原因,因此都可以通过本文的两种方法解决。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。