spring声明事务失效问题
2017-04-17 15:00
225 查看
问题:
在项目开发中遇到了一个spring事务失效的问题,检查配置文档,都没有问题,其他的类中的方法都能进行事务管理,而这个类中的方法却不行。
分析
查看代码发现三个问题:
原因1、在方法内抓了异常,但是没有往外抛。注:以前这个是手动事务,后来改成了声明事务,而异常却没有往外抛。
当然这里也可以使用手动事务,因为现在没有使用connection的事务,所以使用PlatformTransactionManager 。
原因2、保存的方法设置为private,这样spring无法进行代理。spring代理主要两种方式,第一种是jdk动态代理,面向接口,无法代理private方法。 第二种是cglib方式,这个是以子类方式实现,由于方法设置为private导致这里无法进行代理而事务失效。
原因3、Action调用了ServiceA的方法A,而方法A没有声明事务(原因是方法A本身比较耗时而又不需要事务)
ServiceA的方法A调用了自己的方法B,而方法B声明了事务,但是方法B的事务声明在这种情况失效了。
如果在方法A上也声明事务,则在Action调用方法A时,事务生效,而方法B则自动参与了这个事务。
因此,从上面的分析可以看出,methodB没有被AopProxy通知到,导致最终结果是:被Spring的AOP增强的类,在同一个类的内部方法调用时,其被调用方法上的增强通知将不起作用。
而这种结果,会造成什么影响呢:
1:内部调用时,被调用方法的事务声明将不起作用
2:换句话说,你在某个方法上声明它需要事务的时候,如果这个类还有其他开发者,你将不能保证这个方法真的会在事务环境中
3:再换句话说,Spring的事务传播策略在内部方法调用时将不起作用。
解决方案:
1、将该类的所有方法都加上事务,即所有方法都会被代理,这样方法B事务才会生效。
2、调用时使用cglib生成的bean去调用方法B,比如说
而不是直接使用this.B();
在项目开发中遇到了一个spring事务失效的问题,检查配置文档,都没有问题,其他的类中的方法都能进行事务管理,而这个类中的方法却不行。
分析
查看代码发现三个问题:
原因1、在方法内抓了异常,但是没有往外抛。注:以前这个是手动事务,后来改成了声明事务,而异常却没有往外抛。
当然这里也可以使用手动事务,因为现在没有使用connection的事务,所以使用PlatformTransactionManager 。
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); PlatformTransactionManager txManager = (PlatformTransactionManager )BeanLocator.getInstance().getBean("transactionManager"); TransactionStatus transactionStatus = txManager.getTransaction(def); try{ txManager.commit(transactionStatus); } catch (Exception e) { logger.error("数据入库失败,不删除文件 fileName:" + file.getName(), e); txManager.rollback(transactionStatus); }
原因2、保存的方法设置为private,这样spring无法进行代理。spring代理主要两种方式,第一种是jdk动态代理,面向接口,无法代理private方法。 第二种是cglib方式,这个是以子类方式实现,由于方法设置为private导致这里无法进行代理而事务失效。
原因3、Action调用了ServiceA的方法A,而方法A没有声明事务(原因是方法A本身比较耗时而又不需要事务)
ServiceA的方法A调用了自己的方法B,而方法B声明了事务,但是方法B的事务声明在这种情况失效了。
如果在方法A上也声明事务,则在Action调用方法A时,事务生效,而方法B则自动参与了这个事务。
因此,从上面的分析可以看出,methodB没有被AopProxy通知到,导致最终结果是:被Spring的AOP增强的类,在同一个类的内部方法调用时,其被调用方法上的增强通知将不起作用。
而这种结果,会造成什么影响呢:
1:内部调用时,被调用方法的事务声明将不起作用
2:换句话说,你在某个方法上声明它需要事务的时候,如果这个类还有其他开发者,你将不能保证这个方法真的会在事务环境中
3:再换句话说,Spring的事务传播策略在内部方法调用时将不起作用。
解决方案:
1、将该类的所有方法都加上事务,即所有方法都会被代理,这样方法B事务才会生效。
2、调用时使用cglib生成的bean去调用方法B,比如说
public void A(){ serviceA.B() }
而不是直接使用this.B();
相关文章推荐
- spring声明事务失效问题(二)
- spring 声明式事务、异步调用、AOP灯增强类功能 失效问题
- spring+springmvc+mybatis事务失效问题
- 解决spring、springMVC重复扫描导致事务失效的问题
- spring注解实现业务层事务管理,当业务层自调用时,事务失效问题解决
- spring 事务配置以及事务内自我调用失效问题汇总
- spring注解实现业务层事务管理,当业务层自调用时,事务失效问题解决
- Spring Data JPA事务失效问题
- 关于Spring的@Transactional注解失效以及事务无法回滚问题
- spring + springMVC声明式事务失效问题
- 一次想不到的Spring事务失效问题跟踪(事务不会滚)
- Spring 事务失效问题
- spring 的事务问题,事务失效,事务传播
- 解决spring、springMVC重复扫描导致事务失效的问题
- Spring+hibernate的session问题 声明事务管理是否起作用
- spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题
- spring2.5 struts2 hibernate3 时事务配置注意的问题 openSessionInViewFilter web.xml
- 今天用spring 事务出了一个很郁闷的问题
- Spring中事务管理与Hibernate自带事务管理冲突的一个问题
- Spring 多数据源事务配置问题