Spring 事务的使用、隔离级别、@Transactional的使用

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


Spring 事务的使用、隔离级别、@Transactional的使用,Java知识分享,spring,面试,spring事务,java


        Spring事务是Spring框架提供的一种机制,用于管理应用程序中的数据库事务。

        事务是一组数据库操作的执行单元,要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。

Spring事务提供了声明式事务和编程式事务两种方式:

  1. 编程式事务: 编程式事务是通过编写代码来手动管理事务的开始、提交或回滚,开发人员需要显式地调用事务管理器的方法来控制事务的边界。

  2. 声明式事务: 声明式事务是通过在配置文件或注解中声明事务的属性来实现的。开发人员只需要关注业务逻辑,而不需要关心事务的管理。Spring框架会根据注解的配置自动管理事务的开始、提交或回滚。


1. 编程式事务:

        在Spring编程式事务中,DataSourceTransactionManager和TransactionDefinition是两个核心的类:

  1. DataSourceTransactionManager: 它是基于数据源(DataSource)的事务管理器,通过获取连接并控制连接的提交或回滚来管理事务。使用时,需要配置一个数据源(DataSource),用于获取数据库连接。在事务开始时,它会从数据源中获取一个数据库连接,并将该连接绑定到当前线程上下文中。在事务结束时,它会根据事务的提交或回滚状态,来决定是否提交或回滚数据库连接。

  2. TransactionDefinition: 是Spring框架定义的事务属性接口,用于定义事务的一些属性,比如事务的隔离级别、传播行为、超时时间等。

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private DataSourceTransactionManager transactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/del")
    public int del(Integer id) {
        if (id != null && id > 0) {
            // 开启事务
            TransactionStatus transactionStatus = null;
            // 业务操作,进行删除
            int result = 0;
            try {
                transactionStatus = transactionManager.getTransaction(transactionDefinition);
                result = userService.del(id);
                System.out.println("删除成功:" + result);
                transactionManager.commit(transactionStatus); // 提交
            } catch (Exception e) {
                if (transactionStatus != null) {
                    transactionManager.rollback(transactionStatus); // 回滚
                }
            }
            return result;
        }
        return 0;
    }
}

2. 声明式事务:

        编程式事务写起来较麻烦,声明式事务用起来较方便。

        声明式事务可以通过使用 @Transactional 注解来实现:

        当方法执行完成后,如果没有发生异常,事务管理器会自动提交事务;如果发生异常,事务管理器会自动回滚事务。也可以通过在方法上抛出异常手动来触发事务的回滚。

@RestController
@RequestMapping("/user2")
public class UserController2 {
    @Autowired
    private UserService userService;

    @Transactional
    @RequestMapping("del")
    public int del(Integer id) {
        if (id == null || id < 0) return 0;
        int ret = userService.del(id);
        System.out.println("删除:" + id);
        return ret;
    }
}

3. @Transactional 注解的具体使用:

3.1 作用范围: 

@Transactional注解支持修饰方法,也可以修饰类:

  • 修饰方法时:需要注意只能应用到 public 方法上,否则不生效。推荐此种用法。

  •  修饰类时:表明该注解对该类中所有的 public 方法都生效。

3.2 支持参数设置:

这些参数可以根据实际需求进行设置,如果不指定参数,则使用默认值。

  1. value:指定使用的事务管理器的名称。可以通过名称引用已经配置的事务管理器。默认值为空,表示使用默认的事务管理器。

  2. propagation:指定事务的传播行为。可以设置为以下值之一:

    • REQUIRED:如果当前没有事务,则创建一个新的事务;如果当前存在事务,则加入到当前事务中。
    • REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
    • NESTED:在当前事务的嵌套事务中执行。如果当前没有事务,则创建一个新的事务。
    • SUPPORTS:如果当前存在事务,则加入到当前事务中;如果当前没有事务,则以非事务方式执行。
    • MANDATORY:如果当前存在事务,则加入到当前事务中;如果当前没有事务,则抛出异常。
    • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则将当前事务挂起。
  3. isolation:指定事务的隔离级别。可以设置为以下值之一:

    • DEFAULT:使用默认的隔离级别(以连接的数据库隔离级别为准)。
    • READ_UNCOMMITTED:允许读取未提交的数据。
    • READ_COMMITTED:只能读取已提交的数据。
    • REPEATABLE_READ:保证可重复读取,禁止脏读和不可重复读。
    • SERIALIZABLE:保证可串行化的隔离级别,禁止脏读、不可重复读和幻读。
  4. timeout:指定事务的超时时间,单位为秒。如果事务在指定的时间内没有完成,则会被自动回滚。默认值为-1,表示没有超时限制。

  5. readOnly:指定事务是否为只读事务。如果设置为true,则表示只读事务,不允许进行任何修改操作。默认值为false。

  6. rollbackFor:指定哪些异常触发事务的回滚。可以设置为一个异常类或异常类数组。默认情况下,只有运行时异常和Error会触发事务的回滚。

  7. noRollbackFor:指定哪些异常不触发事务的回滚。可以设置为一个异常类或异常类数组。默认情况下,运行时异常和Error会触发事务的回滚。

如图: 如果要加多个参数,可以使用逗号隔开

Spring 事务的使用、隔离级别、@Transactional的使用,Java知识分享,spring,面试,spring事务,java

 

使用注意事项:未检测到异常不回滚

使用 @Transactional 注解是它检测到异常才会回滚,但如果在代码中,使用 try-catch 检测到异常,并在这时程序终止了,那么事务就不会被回滚,这时非常可怕的事情。

例如:

Spring 事务的使用、隔离级别、@Transactional的使用,Java知识分享,spring,面试,spring事务,java

 

解决方案1:从原因入手

        既然是 @Transactional 没有检测到异常,那我们让它检测而到就可以了,所以可以在 catch 中将异常抛出,让 @Transactional 能检测到即可

Spring 事务的使用、隔离级别、@Transactional的使用,Java知识分享,spring,面试,spring事务,java

 

解决方案2:从结果入手

        在 catch 中借助 TransactionAspectSupport 的相关方法来手动回滚事务

Spring 事务的使用、隔离级别、@Transactional的使用,Java知识分享,spring,面试,spring事务,java

3.3 经典面试题:

(1)@Transactional 的工作原理?

@Transactional是Spring框架中用于实现声明式事务管理的注解。它的工作原理是基于AOP(Aspect-Oriented Programming)技术。

  1. 当Spring容器启动时,会扫描所有被@Transactional注解标注的类和方法。

  2. 当调用被@Transactional注解标注的方法时,Spring会通过AOP技术在方法执行前后织入事务管理的逻辑。

  3. 在方法执行前,事务管理器会开启一个新的事务。

  4. 在方法执行过程中,如果发生异常,事务管理器会回滚事务,即撤销之前的操作。

  5. 如果方法执行成功,事务管理器会提交事务,即将之前的操作永久保存到数据库中。

  6. 如果方法执行过程中调用了其他被@Transactional注解标注的方法,事务管理器会根据事务的传播行为来决定是否将这些方法加入到当前事务中。

        需要注意的是,声明式事务只适用于公共方法,即在Spring容器中被代理的方法。如果在同一个类中的非公共方法中调用了带有@Transactional注解的公共方法,事务将不会生效。这是因为Spring使用AOP技术来实现声明式事务,只能拦截公共方法的调用。

(2)Spring 事务失效有哪些原因?

Spring事务失效的原因有以下几种可能:

1. 未正确配置事务管理器:在Spring中,需要配置事务管理器(例如DataSourceTransactionManager)来管理事务。如果未正确配置事务管理器,或者配置有误,可能导致事务失效。

2. 事务注解未生效:使用@Transactional注解来声明事务,但是注解未被正确识别和解析。可能是因为未在配置文件中启用事务注解的解析,或者注解所在的类未被Spring容器扫描到。

3. 异常未被正确抛出:事务的回滚是基于异常的,默认情况下,只有运行时异常和Error会触发事务的回滚。如果在事务方法中捕获了异常并未重新抛出,或者捕获的异常类型不符合回滚条件,事务将不会回滚。

4. 事务传播行为设置不正确:事务的传播行为决定了事务方法与其他事务方法的关系。如果事务方法的传播行为设置不正确,可能导致事务失效或不符合预期。

5. 方法未被代理:声明式事务是通过AOP技术实现的,只有被Spring容器管理的Bean中的方法才会被代理,从而实现事务的管理。如果方法未被代理,事务将不会生效。

6. 数据库不支持事务:某些数据库可能不支持事务,或者事务的隔离级别不被支持。在这种情况下,无法实现事务的管理。

7. 方法被重载:如果一个类中存在多个同名方法,但参数列表不同,而只有其中一个方法被@Transactional注解标注,那么其他同名方法的事务将不会生效。文章来源地址https://www.toymoban.com/news/detail-611399.html

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

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

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

相关文章

  • Spring的事务隔离级别

    Spring的事务隔离级别是用于控制事务并发访问数据库时的行为。Spring框架提供了五个事务隔离级别,分别是: 1. DEFAULT(默认):使用数据库默认的事务隔离级别。在大多数情况下,这等同于使用READ_COMMITTED级别。 2. READ_UNCOMMITTED(读取未提交数据):最低的隔离级别,允许一

    2024年02月09日
    浏览(34)
  • spring事务管理详解和实例(事务传播机制、事务隔离级别)

    目录 1 理解spring事务 2 核心接口 2.1 事务管理器 2.1.1 JDBC事务 2.1.2 Hibernate事务 2.1.3 Java持久化API事务(JPA) 2.2 基本事务属性的定义 2.2.1 传播行为 2.2.2 隔离级别 2.2.3 只读 2.2.4 事务超时 2.2.5 回滚规则 2.3 事务状态 3 编程式事务 3.1 编程式和声明式事务的区别 3.2 如何实现编程式

    2024年02月06日
    浏览(33)
  • Spring使用@Transactional 管理事务,Java事务详解。

    B站视频:https://www.bilibili.com/video/BV1eV411u7cg 技术文档:https://d9bp4nr5ye.feishu.cn/wiki/HX50wdHFyiFoLrkfEAAcTBdinvh 简单来说事务就是一组对数据库的操作 要么都成功,要么都失败。 事务要保证可靠性,必须具备四个特性:ACID。 A:原子性:事务是一个原子操作单元,要么完全执行,要么

    2024年02月11日
    浏览(24)
  • 38、Spring事务的实现方式和原理以及隔离级别

    在使用Spring框架时,可以有两种使用事务的方式,一种是编程式的,一种是申明式的,@Transactional注解就是申明式的。 首先,事务这个概念是数据库层面的,Spring只是基于数据库中的事务进行了扩展,以及提供了一些能让程序员更加方便操作事务的方式。 比如我们可以通过在

    2024年02月16日
    浏览(37)
  • Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

    目录 一、事务的相关配置 1. 添加测试标签 2. 添加对应方法 3. 测试 二、事务的传播行为 三、事务的隔离级别 四、注解配置声明式事务 1. 注册事务注解驱动 2. 加上注解 3. 配置类代替xml文件中的注解事务支持 4. 测试 往期专栏文章相关导读  1. Maven系列专栏文章 2. Mybatis系列专

    2024年02月08日
    浏览(32)
  • MySQL高阶知识点(一)事务的并发问题和隔离级别

    简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。 在 MySQL 中,事务支持是在 引擎层 实现的。 MySQL 是一个支持多引擎的系统,但并不是所有的引擎都支持事务。 如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。

    2024年02月12日
    浏览(23)
  • 【Spring/MySQL数据库系列】数据库事务的特点与隔离级别

    ⭐️ 前面的话 ⭐️ 本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍有关数据库事务的特点以及隔离级别。 📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📌本文由 未见花闻 原创, CSDN 首发! 📆首发时间:🌴2023年5月20日🌴 ✉️坚

    2024年02月05日
    浏览(42)
  • 深入了解 Spring boot的事务管理机制:掌握 Spring 事务的几种传播行为、隔离级别和回滚机制,理解 AOP 在事务管理中的应用

    🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏 《Spring 狂野之旅:从入门到入魔》 🚀 本专栏带你从Spring入门到入魔   这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suzee.blog.csdn

    2024年03月21日
    浏览(71)
  • 事务和事务的隔离级别

    1.4.1.为什么需要事务 事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位(不可再进行分割),由一个有限的数据库操作序列构成(多个DML语句,select语句不包含事务),要不全部成功,要不全部不成功。 A 给B 要划钱,A 的账户-1000元, B 的账户就要+1000元,这两个up

    2024年02月13日
    浏览(31)
  • 数据库——事务,事务隔离级别

    什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行。 事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误

    2024年02月11日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包