Spring声明式事务@Transactional的一些问题的测试及求证

这篇具有很好参考价值的文章主要介绍了Spring声明式事务@Transactional的一些问题的测试及求证。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.Spring的声明式事务@Transactional问题

前提:有两个方法,a方法对a表做修改操作,b方法对b表做修改操作

a方法调用b方法,然后a方法报错,伪代码如下

public void a() {
    //数据库修改操作
    CompensateLogDO compensateLogDO = new CompensateLogDO();
    compensateLogDO.setId(IdWorker.getId());
    compensateLogDO.setCompensateLogType("123");
    compensateLogMapper.insert(compensateLogDO);

    fullCalcErrorService.b();

    int i = 1 / 0;
}

public void b() {
    //数据库修改操作
    FullCalcErrorDO fullCalcErrorDO = new FullCalcErrorDO();
    fullCalcErrorDO.setId(IdWorker.getId());
    fullCalcErrorDO.setRetryCount(0);
    fullCalcErrorDO.setProcessFlag(0);
    fullCalcErrorMapper.insert(fullCalcErrorDO);
}

a方法调用b方法,然后b方法报错,伪代码如下

public void a() {
    //数据库修改操作
    CompensateLogDO compensateLogDO = new CompensateLogDO();
    compensateLogDO.setId(IdWorker.getId());
    compensateLogDO.setCompensateLogType("123");
    compensateLogMapper.insert(compensateLogDO);

    fullCalcErrorService.b();
}

public void b() {
    //数据库修改操作
    FullCalcErrorDO fullCalcErrorDO = new FullCalcErrorDO();
    fullCalcErrorDO.setId(IdWorker.getId());
    fullCalcErrorDO.setRetryCount(0);
    fullCalcErrorDO.setProcessFlag(0);
    fullCalcErrorMapper.insert(fullCalcErrorDO);
    
    int i = 1 / 0;
}

直接上结果:

  • √:数据库插入成功
  • ×:数据库插入失败
    Spring声明式事务@Transactional的一些问题的测试及求证,Spring,spring,Transactional,声明式事务

在 Spring Boot 中,默认情况下,对于单个数据库操作(即单个 SQL 语句的执行),是采用自动提交的方式。这意味着每次执行单个数据库操作后,都会立即将数据提交到数据库,不会等待其他操作或事务的完成。

2.@Transactional数据库连接问题

声明式事务管理建立在 AOP 之上的。其本质是通过 AOP 功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前启动一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

也就是方法上加了@Transactional,在调用方法时就会获取一个数据库连接,并占用连接到方法结束;而不加@Transactional,只有执行到数据库(读或写)操作时才会获取一个数据库连接,数据库操作执行完就会释放连接

测试验证:

1.在两个方法都不加在@Transactional注解测试,分别在com.zaxxer.hikari.pool.HikariPool#getConnection()org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection打上断点,执行到第一个数据库操作,进入断点,可以看到数据库连接为HikariProxyConnection@1230471455,释放断点,继续执行到第二个数据库操作,又会进入断点,可以看到数据库连接为HikariProxyConnection@1135602287,可以证明只有执行到数据库(读或写)操作时才会获取一个数据库连接,数据库操作执行完就会释放连接

Spring声明式事务@Transactional的一些问题的测试及求证,Spring,spring,Transactional,声明式事务
Spring声明式事务@Transactional的一些问题的测试及求证,Spring,spring,Transactional,声明式事务

2.在a方法上加@Transactional注解,b方法不加@Transactional注解,还是分别在com.zaxxer.hikari.pool.HikariPool#getConnection()org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin打上断点,方法一执行,就会获取数据库连接,这里是用代理获取的,可以看到数据库连接为HikariProxyConnection@1868392374,释放断点继续执行,可以发现后续数据库操作不会再获取连接,可以证明方法上加了@Transactional,在调用方法时就会获取一个数据库连接,并占用连接到方法结束

Spring声明式事务@Transactional的一些问题的测试及求证,Spring,spring,Transactional,声明式事务

3.@Transactional(readOnly = true)问题

@Transactional(readOnly = true) 是Spring Framework中用来声明只读事务的注解。当一个方法被标记为@Transactional(readOnly = true)时,Spring将会确保在该方法的执行过程中,不会对数据库进行写操作,即只进行读操作。进行写操作会报错!!!

虽然@Transactional(readOnly = true)的主要目的是为了告诉Spring该方法只涉及读操作,但是它在底层仍然会占用一个数据库连接,这是因为Spring需要通过数据库连接来执行查询操作。然而,由于该方法只进行读取操作,Spring会尽可能地使用数据库的只读连接,从而减少对数据库的负担。

@Transactional(readOnly = true)主要的优势是在于告诉Spring该方法只进行读取操作,从而让Spring能够优化数据库连接的使用。它适用于那些纯粹的查询方法或者只读取数据而不涉及更新的业务逻辑。

什么时候使用@Transactional(readOnly = true)呢?

  • 纯读取操作: 如果某个方法完全是只读操作,不涉及数据库的写入(INSERT、UPDATE、DELETE),那么可以使用 @Transactional(readOnly = true) 来标记这个方法。这样Spring将会优化数据库连接的使用,使用只读连接,从而减少对数据库的负担。

  • 提高并发性能: 在高并发读取密集的场景下,通过将一些只读的查询操作标记为 @Transactional(readOnly = true) 可以提高并发性能。因为只读事务通常会使用数据库的共享锁(Shared Lock),不会阻塞其他只读事务,这样可以减少数据库的锁竞争,提高并发能力。

  • 避免意外修改: 使用 @Transactional(readOnly = true) 可以防止开发人员在只读方法中意外执行了写入操作。如果在只读事务中尝试执行写入操作,会抛出异常,从而避免数据的修改。文章来源地址https://www.toymoban.com/news/detail-619636.html

到了这里,关于Spring声明式事务@Transactional的一些问题的测试及求证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 面试好题:@Transactional声明式事务注解什么时候会失效?

    今天来分享一道比较有意思的面试题,“@Transactional声明式事务注解什么时候会失效?”。 对于这个问题,我们一起看看考察点和比较好的回答吧!     这个问题就是面试官想考察我们对@Transactional注解有没有深刻的认识,以及日常开发中是否善于积累,认真思考。 下面我

    2024年02月09日
    浏览(39)
  • Spring 声明式事务不生效的问题如何解决

    Spring 声明式事务不生效的问题如何解决 Spring 的声明式事务通常使用 @Transactional 注解来实现。如果你发现声明式事务不生效,可能有几个原因导致这种情况。以下是一些可能的解决方法: 确保配置正确 : 确保在 Spring 的配置文件(如 applicationContext.xml)中启用了事务管理器

    2024年02月21日
    浏览(35)
  • Spring的事务(@Transactional)

    Spring事务的本质,其实就是通过 Spring AOP 切面技术 Spring事务支持2种使用方式 声明式事务(注解方式) 编程式事务(代码方式):代码需要手动控制,比较繁琐,一般不使用 SpringBoot 默认开启了事务 Spring Spring的事务是使用AOP来实现的,在执行目标方法的前和后,加上了事务

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

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

    2024年02月11日
    浏览(31)
  • Spring——事务注解@Transactional【建议收藏】

    在某些业务场景下,如果一个请求中,需要同时写入多张表的数据或者执行多条sql,为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到事务;Spring框架下,我们经常会使用@Transactional注解来管理事务; 本篇介绍Spring的事务注

    2024年02月03日
    浏览(48)
  • Spring @Transactional事务传播机制详解

    我们日常工作中极少使用事务传播级别,单纯只是使用事务和rollbackfor抛出异常来解决事务问题,但其实我们很多时候使用的是不正确的,或者说会造成事务粒度过大,本文详解一下事务传播级别,也让自己更好地处理事务问题。 1.什么是事务传播机制? 举个栗子,方法A是一

    2024年02月14日
    浏览(43)
  • 【spring(四)】Spring事务管理和@Transactional注解

    🌈键盘敲烂,年薪30万🌈 目录 Spring中的事务管理 问题抛出: 解决方案: @Transactional注解: rollbackFor属性: propagation属性: 应用: 📕总结 知识回顾: ❓什么是事务 事务是对数据操作的集合,它是数据操作的最小执行单位,也就是说,要么一个事务中操作全部执行完毕,

    2024年01月17日
    浏览(49)
  • 【JavaEE】Spring事务-事务的基本介绍-事务的实现-@Transactional基本介绍和使用

    【JavaEE】Spring 事务(1) 比如跟钱相关的两个操作: 第一步操作:小马卡里 - 100元 第二步操作:老马卡里 + 100元 这就是一个事务,捆在一起的一组行为,就是事务 而它能保证的是,这个行为的原子性,一致性,隔离性,持久性: 两个操作都成功 两个操作都失败 要么一起成

    2024年02月11日
    浏览(44)
  • Spring5学习随笔-事务属性详解(@Transactional)

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 事务是 保证业务操作完整性的一种数据库机制 事务的4特点:ACID A 原子性 C 一致性 I 隔离性 D 持久性 JDBC: Connection.setAutoCommit(false) Connect

    2024年02月05日
    浏览(40)
  • Spring 事务的使用、隔离级别、@Transactional的使用

            Spring事务是Spring框架提供的一种机制,用于管理应用程序中的数据库事务。         事务是一组数据库操作的执行单元,要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。 Spring事务提供了声明式事务和编程式事务两种方式: 编程式事务:

    2024年02月15日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包