前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring声明事务失效问题

spring声明事务失效问题

作者头像
一笠风雨任生平
发布2019-08-02 11:10:54
5530
发布2019-08-02 11:10:54
举报
文章被收录于专栏:服务化进程

问题:

在项目开发中遇到了一个spring事务失效的问题,检查配置文档,都没有问题,其他的类中的方法都能进行事务管理,而这个类中的方法却不行。

分析

查看代码发现三个问题:

原因1、在方法内抓了异常,但是没有往外抛。注:以前这个是手动事务,后来改成了声明事务,而异常却没有往外抛。

当然这里也可以使用手动事务,因为现在没有使用connection的事务,所以使用PlatformTransactionManager 。

代码语言:javascript
复制
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,比如说

代码语言:javascript
复制
public void A(){ 
        serviceA.B()
}

而不是直接使用this.B();

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档