Spring事务失效常见的八种场景
admin
2024-02-04 06:11:35
0

文章目录

    • 1. 方法自调用
    • 2. 方法修饰符为private
    • 3. 方法是final的
    • 4. 单独的线程调用
    • 5. Spring中没加@Configuration注解
    • 6. 异常被吃掉
    • 7. 类没有被Spring管理
    • 8. 数据库没有开启事物

1. 方法自调用

第一类,@Transactional注解未生效情况,其实这种并不是事物失效,仅仅是注解失效,注解写了更没写一样

解决方案:

  • 将被调用的方法拆到单独的bean中,让切面起作用
  • 自己注入自己获取代理类
  • @EnableAspectJAutoProxy(exposeProxy = true) + UserService userService = (UserService) AopContext.currentProxy();

Spring事务是基于AOP的,只有当代理对象调用某个方法时,Spring的事务才会生效,而在一个方法中调用this.xxx()方法时,由于this并不是代理对象,所以会导致事务失效

@Transactional
public void a(){jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();
}// 自调用
public void b(){// 由于调用者并不是代理对象,所以切面失败导致事物失效a();
}

还有一种情况

// 此时相当于`a`方法上面根本就没贴事物注解一样
@Transactional(propagation = Propagation.NEVER)
public void a(){jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();
}// 调用方法也加了事物注解,此时会进行回滚,但是是由b方法的事物就行回滚的
@Transactional
public void b(){// 由于调用者并不是代理对象,所以切面失败导致事物失效a();
}

所以解决方案就是用代理对象调用即可

public class UserService {@Autowired // 自己注入自己private UserService userService;@Transactionalpublic void a(){jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();}// 事物生效public void b(){userService.a();}
}

或者可以通过代理上下文获取当前类的代理对象,但是这种需要我们在配置类上面设置属性@EnableAspectJAutoProxy(exposeProxy = true)

public class UserService {@Transactionalpublic void a(){jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();}// 事物生效public void b(){// 获取当前类的代理对象UserService userService = (UserService) AopContext.currentProxy();userService.a();}
}

2. 方法修饰符为private

  • cglib代理是基于父子类的,如果方法私有无法在子类中获取到,无法重写,只能执行父类的方法,但是父类中没有jdbcTemplate,会抛出NPE
  • 多态口诀:new谁调用谁的方法,谁创建使用谁的属性
public class UserService {// cglib代理是基于父子类的,如果方法私有无法在子类中获取到,只能执行父类的方法,但是父类中没有`jdbcTemplate`,`NPE`@Transactionalprivate void a(){jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();}
}

3. 方法是final的

同上,代理类无法重写代理的方法

4. 单独的线程调用

Mybatis或者JdbcTemplate执行SQL时,会从ThreadLocal中去获取数据库连接对象,如果开启事物的线程和执行SQL的线程不是同一个线程,就拿不到数据库连接对象,这样,Mybatis或者JdbcTemplate就会重新创建一个数据库连接用来执行SQL,如果这个事物自动事物提交autocommit默认开启的话,就不会因为异常而进行回滚

public class UserService {// 事物失效@Transactionalprivate void a(){new Thread(() -> {jdbcTemplate.execute("insert into t1 values(1)");throw new RuntimeException();}).start();}
}

5. Spring中没加@Configuration注解

在Spring中,由于MybatisJdbcTemplate会从ThreadLocal中获取数据库连接,但是ThreadLocal里面存的是map,即ThreadLocal>的结构

如果没有添加@Configuration注解,会导致Map中存的DateSource和MybatisJdbcTemplate对象不相等,从而拿不到数据库连接,导致自己会新建一个,从而导致事物失效

注意:在SpringBoot中由于自动装箱,不会出现这种问题

6. 异常被吃掉

Spring默认只会对RuntimeExceptionError进行回滚

7. 类没有被Spring管理

8. 数据库没有开启事物

相关内容

热门资讯

和讯投顾周翔:超级主力完成出货... 当前A股市场出现了一些令人关注的现象,确实让不少投资者感到困惑和不安。今天上证50ETF成交创下了1...
业务承压、回款滞后!成都路桥2... 1月22日,成都路桥(002628)披露2025年度业绩预告,预计2025年归母净利润亏损6500万...
美股爆发,黄金直拉!特朗普:将... 1月22日晚间,美股全线走高。消息面上,美国总统特朗普最新表示,正在推进中的格陵兰岛协议将赋予美国“...
原创 楼... 作为一名长期关注中国房地产市场的观察者,我见证了无数家庭在这个市场中的起伏。扎根于地产研究的十八年经...
六大行集体公告!落实个人消费贷... 人民网北京1月22日电 (记者罗知之)近日,工商银行、农业银行、中国银行、建设银行、交通银行、邮储银...
资本密集型领域正在成为外资投资... 人民网罗马1月21日电 (记者郑彬)日前,联合国贸易和发展会议(简称:联合国贸发会议)最新发布的《全...
为会展行业注入新动能 2026... 深圳商报·读创客户端记者 刘娥 在科技变革与产业融合的双重驱动下,中国会展业正迎来前所未有的发展机遇...
原创 狂... 在各类资产起起伏伏的当下,有一个板块正在悄悄走出独立行情。近日,包括高盛、花旗在内的多家国际大行分析...
郑州机场上线“无感通关”,单件... 【大河财立方 记者 陈诗昂】“这次从韩国回来,通关流程简便了,拿到行李后,不用排队搬运过X光机,几分...
原创 印... 2025年11月,印度五大炼油企业在制裁截止日11月21日之前,大规模囤积俄罗斯石油,在12月份没有...
收评:创业板指探底回升涨超1%... 【收评:创业板指探底回升涨超1% 商业航天概念爆发】财联社1月22日电,市场午后震荡回升,三大指数集...
富国消费主题混合C基金近3年单... 近期,富国基金旗下富国消费主题混合基金的表现引起市场关注。 富国消费主题混合基金成立于2014年12...
宏利基金被曝与特斯拉存在诉讼 ... 近期,上海市高级人民法院披露的一则开庭公告显示,特斯拉(上海)有限公司已起诉宏利基金管理有限公司(下...
95亿消费电子大佬,拟“接盘”... 雷达财经出品 文|丁禹 编|孟帅 1月20日,港股上市公司 TCL电子联手索尼,抛出一则震动消费电子...
TikTok美国出售交易预计本... 据美国数字新闻媒体SEMAFOR报道,中美双方已达成协议,以美国投资者为主的财团将参与TikTok美...
金饰克价,1500元!“轻黄金... 近日,首饰黄金每克报价突破1500元引发热议。1月22日,中国证券报记者走访北京地区多家品牌金店看到...
2025年离境退税销售额同比增... 2025年,上海入境游迎来强势增长,全年累计接待入境游客创历史新高,达到936.02万人次,同比大幅...
邵东市举办“讲台育桃李,健康护... 大众卫生报·新湖南客户端1月20日讯(通讯员 曾秀丽 罗邵陵)为提升女性健康素养,强化自我保护意识,...
华翔股份大宗交易折价成交67.... 华翔股份01月22日大宗交易平台共发生4笔成交,合计成交量67.50万股,成交金额1150.88万元...
年内已经上涨37%,明早的英特... 今年以来,英特尔股价累计涨幅已达37%,1月21日收盘价报54.25美元,创2022年1月以来新高。...