Springboot 整合事务

这篇具有很好参考价值的文章主要介绍了Springboot 整合事务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

事务介绍

事务的ACID特性

事物的隔离级别

事务的传播机制

只读

事务超时

回滚规则

事务的配置方式

声明式事务

编程式事务

@Transactional失效问题


事务介绍

Spring 事务的对于数据库的操作,要么执行,要不都不执行,在事务中都执行成功就会提交失败就会发生回滚。

事务的ACID特性

原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
事务隔离(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
 

事物的隔离级别

未提交读(Read uncommitted),最低的隔离级别,允许“脏读”(dirty reads),事务可以看到其他事务“尚未提交”的修改。如果另一个事务回滚,那么当前事务读到的数据就是脏数据。
提交读(read committed),一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
可重复读(repeatable read),一个事务可能会遇到幻读(Phantom Read)的问题。幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
串行化(Serializable),最严格的隔离级别,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。虽然 Serializable 隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用 Serializable 隔离级别。

事务的传播机制

PROPAGATION_REQUIRED
Spring默认的传播机制,能满足绝大部分业务需求,如果外层有事务,如果外部方法开启事务并且是 Propagation.REQUIRED 的话,所有 Propagation.REQUIRED 修饰的内部方法和外部方法均属于同一事务一块提交,一块回滚。如果外层没有事务,新建一个事务执行
PROPAGATION_REQUES_NEW
该事务传播机制是每次都会新开启一个事务,同时把外层事务挂起,当当前事务执行完毕,恢复上层事务的执行。如果外层没有事务,执行当前新开启的事务即可
PROPAGATION_SUPPORT
如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务
PROPAGATION_NOT_SUPPORT
该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码
PROPAGATION_NEVER
该传播机制不支持外层事务,即如果外层有事务就抛出异常
PROPAGATION_MANDATORY
与NEVER相反,如果外层没有事务,则抛出异常
PROPAGATION_NESTED
该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。

只读

如果一个事务只对数据库执行读操作,那么该数据库就可能利用那个事务的只读特性,采取某些优化措施。通过把一个事务声明为只读。

事务超时

指一个事务所允许执行的最长时间,如果在超时时间内还没有完成的话,就自动回滚。

回滚规则

在默认设置下,事务只在出现运行时异常(runtime exception)时回滚,而在出现受检查异常(checked exception)时不回滚,不过,可以声明在出现特定受检查异常时像运行时异常一样回滚。同样,也可以声明一个事务在出现特定的异常时不回滚,即使特定的异常是运行时异常。

事务的配置方式

声明式事务

在Springboot中声明式事务一般使用@Transactional注解,至于@EnableTransactionManagement注解不使用也可以。声明式事务是建立在AOP上的,我们的程序会通过注解的方式提供元数据,AOP与事务元数据结合产生一个代理,当执行方法的时候,拦截器TransactionInterceptor会对目标方法进行拦截,然后在执行目标方法的前后调用代理。其本质是在目标方法之前创建或者加入一个事务。@Transactional注解可以用在接口定义,接口方法和类的公共方法上。

代码如下

    @Transactional
    @GetMapping("/test")
    public void test1(){
        
    }

编程式事务

Spring提供了三种支持编程式事务的方式,使用TransactionTemplate或者TransactionalOperator或

TransactionManager,这里主要介绍TransactionTemplate,使用回调方法让应用程序代码从获取和释放事务性资源的样板操作中释放出来,也就意味着不用手动开启事务或者关闭事务,应用程序只关注业务。代码如下

    @Autowired
    TransactionTemplate transactionTemplate;
    
    @GetMapping("/test")
    public void test1(){
        transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                return null;
            }
        });
    }

@Transactional失效问题

1. 是否使用了 try catch 进行了异常捕获,并且捕获之后,没有通过 throw new RuntimeException();进行异常抛出。因为对于 spring aop异常捕获原理,被拦截的方法需要显示的抛出异常,并不能进行任何处理,这样 aop 代理才能捕获到方法的异常,才能进行事务的回滚操作;默认清空下,aop只捕获 RuntimeException 的异常,但是可以通过配置来捕获特定的异常并回滚。对于这种情况不是RuntimeException异常,可以在抛出异常的时候,然后添加下面这行代码。

@Transactional(rollbackFor=Exception.class)

也可以在 catch语句中加:TransactionAspectsupport.currentTransactionstatus().setRollbackonly();

2.排查是不是产生了自调用的问题。在 spring 的 aop 代理下,只有目标方法被外部调用,目标方法才由 spring 生成的代理对象来管理;若统一类中的其他没有用@Transactional注解进行修饰的方法内部调用了用@Transactional注解进行修饰的方法,有@Transactional注解的方法的事务将会被忽略,不发生回滚。代码如下这种情况就不会就不会发生回滚,代码参考如下

 @GetMapping("/test")
    public void test1(){
        test2();
    }

    @Transactional
    public void test2(){
        tbShopMapper.deleteById(1);
        int m=19/0;
    }

如果要生效可以把注解放在类上。

3 @Transactional注解只被应用到 public修饰的方法上;如果在 protected、private等修饰的方法上,@Transactional 注解不会报错,但是这个注解的将不会生效。

4.@Transactional注解不会对当前修饰的方法的子方法生效。比如:我们在方法A中声明了@Transactional注解,但是A方法的内部调用的方法B,其中方法B进行了数据库的操作,但是改部分的异常被方法B进行了处理并且没有进行抛出,这样的话事务是不会生效的。反之,如果方法B声明了@Transactional,但是方法A没有声明@Transactional,A方法内部调用B方法,事务也是不会生效的。文章来源地址https://www.toymoban.com/news/detail-437455.html

到了这里,关于Springboot 整合事务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis(发布订阅、事务、redis整合springboot、集成 Spring Cache)

    目录 一.redis的发布订阅 1、什么 是发布和订阅 2、Redis的发布和订阅 3、发布订阅的代码实现 二.Redis事务 1.事务简介 1、在事务执行之前 如果监听的key的值有变化就不能执行 2、在事务执行之前 如果监听的key的值没有变化就能执行 3、Exec之前就出现错误 4、Exec之后出现的错误

    2024年01月24日
    浏览(50)
  • Redis-redis事务、乐观锁、Jedis、SpringBoot整合Redis

    1、事务 ①开启事务、执行事务 ② 取消事务 ③ 编译性异常(代码有问题! 命令有错!),事务中所有的命令都不会被执行! ④ 运行时异常(I/O),如果事务队列中存在语法行,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常! (区别于直接命令错误

    2024年01月16日
    浏览(41)
  • 【SpringBoot】--03.数据访问、基础特性(外部化和内部外配置、整合JUnit)

    学习视频: 尚硅谷SpringBoot3视频 SpringBoot 整合 Spring 、 SpringMVC 、 MyBatis 进行 数据访问场景 开发 勾选之后会导入以下包 安装 MyBatisX 插件,帮我们生成Mapper接口的xml文件即可 在接口处 : Alt + 回车 必须把mapper的xml文件映射位置在配置文件定义! 而驼峰命名转换建议也开启 编

    2024年02月15日
    浏览(39)
  • 【万字长文】SpringBoot整合Atomikos实现多数据源分布式事务(提供Gitee源码)

    前言:在最近的实际开发的过程中,遇到了在多数据源的情况下要保证原子性的问题,这个问题当时遇到了也是思考了一段时间,后来通过搜集大量资料与学习,最后是采用了分布式事务来解决这个问题,在讲解之前,在我往期的博客提前搭好了一个SpringBoot整合MyBatis搭建M

    2024年02月14日
    浏览(40)
  • 【SpringBoot3】--03.数据访问、基础特性(外部化和内部外配置、整合JUnit)

    学习视频: 尚硅谷SpringBoot3视频 SpringBoot 整合 Spring 、 SpringMVC 、 MyBatis 进行 数据访问场景 开发 勾选之后会导入以下包 安装 MyBatisX 插件,帮我们生成Mapper接口的xml文件即可 在接口处 : Alt + 回车 必须把mapper的xml文件映射位置在配置文件定义! 而驼峰命名转换建议也开启 编

    2024年02月16日
    浏览(39)
  • 最新版 !快速掌握 JDK17 + springboot3 + springcloud Alibaba : 10、Seata 整合实现分布式事务

    上一节成功启动了seata,传送门: https://blog.csdn.net/qq_16089135/article/details/133989446 1.1 官方文档 中文文档 Seata 是什么 1.2 模式分类 AT :基于支持本地 ACID 事务的关系型数据库。 Java 应用,通过 JDBC 访问数据库。 整体机制:二阶段提交。 一阶段:业务数据和回滚日志记录在同一

    2024年02月06日
    浏览(53)
  • Springboot项目目录介绍

    一个标准的 Spring Boot 项目主要包含如下目录及其文件: src:源代码目录,包括 main 和 test 两个子目录。 pom.xml:Maven 的项目配置文件,包含了该项目的依赖管理、插件配置等。 src/main 目录: java:Java 代码目录,包含了该项目的核心代码。 Application.java:Spring Boot 应用程序的

    2023年04月25日
    浏览(37)
  • SpringBoot系列:事物创建过程(二)

    SpringBoot系列:事物加载过程(一) SpringBoot系列:事物创建过程(二) SpringBoot系列:事物提交回滚过程(三) 上一节讲述了事物的加载过程,最后生成代理文件,放到spring容器中。 代理类继承了 被代理类, 实现了两个 SpringProxy , Advised , Factory 接口, methodInterceptor 是 Dynami

    2023年04月09日
    浏览(34)
  • 【SpringBoot3】Spring Boot 3.0 介绍以及新特性

    Spring Boot 3.0 是 Spring Boot 框架的一个重要版本,它在保持了 Spring Boot 的一贯优点的同时,也进行了一些重要的改进和更新。 首先,Spring Boot 3.0 对 Java 版本的要求进行了更新。这个版本要求使用 Java 17 作为最低版本,以利用最新的语言特性和性能改进。如果你正在使用的是

    2024年01月17日
    浏览(84)
  • EMQ的介绍及整合SpringBoot的使用

    首先先了解一下底层的协议: 1. MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅 (publish/subscribe)模式的\\\" 轻量级 \\\"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。 MQTT最大优点在于,可以 以极少的代码和有限的带宽,为连接远程

    2024年02月11日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包