当前位置: 首页 > news >正文

spring - 十二种事务失效场景

 

目录

​编辑

一、方法内部调用

1、原理:

2、结论:

 3、解决方法:

1. 增加一个service,把一个事务的方法移到新增加的service方法里面,然后进行注入再调用

2. 在自己类中注入自己

3. 通过AopContentent

二、访问权限不是pubilc

三、方法用final修饰

四、没有被spring管理

五、数据库不支持事务

解决方案:使用InnoDB等支持事务的数据库引擎。

六、没有开启事务

七、错误的事务传播

八、自己捕获了异常

 1、 原因:

2.、解决方案:

        手动抛出异常或配置rollbackFor属性

九、手动抛出别的异常

十、自定义回滚异常

十一、多线程调用

十二、嵌套事务回滚过头

解决方法:


一、方法内部调用

在同一个类的service中,调用其他的事务方法

@Service
public class DemoService {

    @Transactional
    public void query(Demo demo) {
        save(demo) ;
    }

    @Transactional
    public void save(Demo demo) {

    }

}

        可以看到,query方法调用了save的方法,由于spring的事务实现是因为aop生成代理,这样是直接调用了this对象,所以也不会生成事务。

1、原理:

        当spring容器启动的时候,发现有@EnableTransactionManagement注解,此时会拦截所有bean的创建,然后会扫描一下bean上是否有@Transaction注解(类、接口、或者方法上有这个注解都可以),如果有这个注解,spring会通过aop的方式给这个bean生成代理对象(代理对象中存在本类对象),代理对象中会增加一个拦截器,拦截器会拦截bean中public方法的执行,会在方法执行前启动事务,方法执行完毕之后提交或者回滚事务。

2、结论:

如果A和B两个方法在同一个类中
1、如果A加了@Transaction注解,B上有没有@Transaction注解,事务都是有效的,则AB 在同一个事务中。

2、如果A不加@Transaction注解,B上有没有@Transaction注解,事务都是无效的。

如果A和B两个方法不在同一个类中
1、如果A加了@Transaction注解,B上有没有@Transaction注解,事务都是有效的。

2、如果A不加@Transaction注解,B加了@Transaction注解,只有B是有事务的。

3、如果A不加@Transaction注解,B也不加@Transaction注解,A和B都是没有事务的。

简单理解:

        在同一个类中,只要A加了@Transaction注解,无论B加不加注解,AB都在同一个事务中,事务有效。

        如果AB在同一个类中,A不加注解,B加了注解,则事务失效;如果AB不同类,A不加注解,B加了注解,则只有B有事务。

原因分析:

        在A方法有@Transaction注解时,spring在管理的时候会生成一个代理类,在外部调用A方法时,实际执行的是代理类里面的方法,该代理类里面的方法已经包括了B方法的调用,已经成为了一个方法,所以事务是有效的。

 3、解决方法:


1. 增加一个service,把一个事务的方法移到新增加的service方法里面,然后进行注入再调用

@Service
public class DemoTwoService {
    
    @Transactional
    public void save(Demo demo) {

    }
}

@Service
public class DemoService {

    @Autowired
    DemoTwoService demoTwoService;

    @Transactional
    public  void query(Demo demo) {
        demoTwoService.save(demo);
    }
}

2. 在自己类中注入自己

@Service
public class DemoService {

    @Autowired
    DemoService demoService;

    @Transactional
    public  void query(Demo demo) {
        demoService.save(demo);
    }

    @Transactional
    public void save(Demo demo) {

    }
}

由于这种写法基于spring的三级缓存不会导致,循环依赖的问题出现

3. 通过Aop

相关文章:

  • python虚拟环境安装opus(windows)
  • 大模型重点1 【综述-文字版】
  • 深度解析提示词工程:让AI成为你的超级助手(2025实战指南)
  • CI/CD(四) docker-compose 安装harbor
  • WebGPU 是比 WASM 更好的选择吗? (Is WebGPU a Better Choice Than WASM? )
  • 鸿蒙开发之背景图片的使用
  • mongoShake数据迁移
  • 什么是Vue.js
  • 网管软件Zabbix3.4.8 使用笔记 - 更改记录保留的时间 20250325
  • 【Ai】--- 可视化 DeepSeek-r1 接入 Open WebUI(超详细)
  • 深入理解数据类型、建表与数据库引擎
  • K8S——PaaS平台pod调度机制
  • Rust从入门到精通之进阶篇:16.智能指针
  • 选素数--线性筛
  • 网络基础-路由器和交换机工作配置
  • Redis--redis客户端
  • NodeJs之fs模块
  • Gunicorn部署指南:核心参数详解与实践
  • (UI自动化测试web端)第二篇:元素定位的方法_css定位之ID选择器
  • 【Spring AI】基于专属知识库的RAG智能问答小程序开发——功能优化:用户鉴权主体功能开发
  • 国家发改委:正在会同有关方面,加快构建统一规范、协同共享、科学高效的信用修复制度
  • 视频丨习近平在河南洛阳市考察调研
  • 外交部发言人就第78届世界卫生大会拒绝涉台提案发表谈话
  • 鸿蒙电脑正式发布,国产操作系统在个人电脑领域实现重要突破
  • 网络直播间销售玩具盲盒被指侵权,法院以侵犯著作权罪追责
  • 1至4月国家铁路发送货物12.99亿吨,同比增长3.6%