首页 > 其他分享 >SpringJpa事务和缓存

SpringJpa事务和缓存

时间:2024-10-25 16:34:38浏览次数:7  
标签:事务 缓存 SpringJpa serviceA 调用 方法 findByName

背景,一个service,有一个方法serviceA里面调用两个update方法,一个findByName方法。其中serviceA和update方法上都上有@transactional注解,而findByName上没有。示例如下:

servcieA{
updateByName()
updateById()
findByName()
}

先说结论,这个时候具体事务的变化如下:

  1. serviceA本身会先创建一个事务
  2. updateByName获取service创建的事务
  3. updateById也获取service创建的事务
  4. findByName并不会获取事务,所以是没有事物的
  5. 方法结束serviceA提交该事务

下面是源码分析,如果贴一大段源码,再写一大段注释,看起来也很累,为了方便理解,也不记录代码细节,同样直接说结论。

类名:org.springframework.transaction.interceptor.TransactionAspectSupport

  • 方法名:invokeWithinTransaction

    该方法中的逻辑大致可以抽象为

    1. 读取事务配置:根据方法上,接口上,还有动态代理的实现类上是否有注解,来决定是否有事务配置

    2. 创建或者获取事务:如果没有事务配置,不会走这里

    3. 执行方法:反射调用原方法

    4. 提交事务:判断事务是否新建,如果不是的话,则不会提交

  • 方法名:createTransactionIfNecessary

    该方法根据名字就可以判断出来,如果需要就创建一个事务,如果不需要就获取当前事务,但是有几点需要解释下

    • 在方法调用之前,ThreadLocal的一个map里面已经有一个对象
    • 当serviceA被调用,会把这个对象取出来,isTransactionActive改为True,并且开启这个事务
    • updateByName被调用,也会获取这个对象,这时候isTransactionActive已经是true,那么就不需要重新创建事务了
  • 方法名:commitTransactionAfterReturning

    该方法从名字也可以看出来,原方法returen之后去提交这个事务,也有几点说明

    • 在我们背景设定下,当两个update方法执行之后,也会走到这里,但是由于status.isNewTransaction是false,并不会真的提交
    • 而当serviceA方法返回时,status.isNewTransaction是true,才会走真的提交逻辑

这时候引入了一个新的问题,为什么findByName可以读取到update之后的数据?

这个暂时没看相关源码,所以先问下chatgpt,回头空了可以再看下源码,给出个确切的答案。

即使 `findByName` 方法没有标记 `@Transactional` 注解,它也能读取到更新后的数据,因为它是在**当前事务的上下文**中执行的。因为在同一个 `Persistence Context` 中,所有的数据变更和查询都共享同一个一级缓存:

1. **共享的事务上下文**:由于 `findByName` 是在同一个 `service` 实例内部调用的,即使没有 `@Transactional` 注解,Spring 也会将其纳入已有事务中,从而共享了当前的事务上下文。
2. **缓存的一致性**:一级缓存能够确保事务内的数据一致性,已经更新的数据会立刻反映在缓存中,因此 `findByName` 能查询到更新后的数据。

标签:事务,缓存,SpringJpa,serviceA,调用,方法,findByName
From: https://www.cnblogs.com/my-king/p/18502838

相关文章

  • MySQL 事务详解
    在数据库管理系统中,事务是一个非常重要的概念,MySQL也不例外。本文将详细介绍MySQL中的事务,包括事务的定义、四大特性、提交与回滚代码样例、并发问题以及隔离等级等方面的内容。一、事务定义事务是一个逻辑工作单元,它是一组数据库操作的集合,这些操作要么全部成功执行,要......
  • PbootCMS后台自动清理缓存runtime文件夹
    PbootCMS后台自动清理缓存进入后台管理:登录PbootCMS后台管理系统。配置自动清理缓存:进入“系统设置”->“缓存管理”。找到“自动清理缓存”选项,设置自动清理的时间间隔。保存设置。详细步骤方式一:通过后台清理缓存登录后台:打开浏览器,输入你的PbootCMS后......
  • etcd之etcd分布式锁及事务(四)
    1、etcd分布式锁及事务1.1前言分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这......
  • Spring中三级缓存如何解决循环依赖的
    Spring中是如何解决循环依赖的前言我们都知道,Spring时使用了三级缓存来解决的循环依赖问题。但是三级缓存是什么?三级缓存又是如何解决循环依赖的呢?为什么需要三级缓存,二级不行吗?带着这些问题,我们一起来研究一下Spring的源码,揭秘上面的问题。SpringBean的生命周期要说要S......
  • 事务回顾及使用Seata解决分布式事务
    目录一、事务回顾1、什么是事务2、事务的作用3、事务ACID四大特性4、事务的并发二、Seata之原理简介1、TC、TM、RM三大组件2、分布式事务的执行流程3、AT模式如何做到对业务的无侵入3.1、一阶段加载3.2、二阶段提交3.3、二阶段回滚三、使用SEata添加分布式事务1......
  • vue3,清除缓存,重新安装依赖
     vue3,清除缓存,重新安装依赖如果你正在使用Vite,尝试清除缓存或重启开发服务器:#清除缓存rm-rfnode_modules/.vite #或者重启开发服务器npmrundev #或者yarndev----------------------------------------------vue3重新安装依赖 如果上述步骤都不能解决......
  • 数据库事务耗时过长导致Could not retrieve transaction read-only status from serve
    背景 [11-0602:02:09:005][ERROR]-DruidDataSource-discardconnectionjava.sql.SQLException:Couldnotretrievetransactionread-onlystatusfromserverCausedby:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:Communicationslinkfailure......
  • Spring事务底层源码解析(二)
    今天根据具体的业务代码场景去分析spring事务的源码流程,其中事务传播属性还是PROPAGATION_REQUIRED首先看下第一种业务场景,testTransaction1方法上加了@Transactionl注解,注解中调用了insertTransactionOne(),insertTransactionTwo()方法,这两个方法上面也都加了@Transactionl注......
  • mysql 行级锁,四种事务隔离级别,两种读
    只说innodb存储引擎1.默认使用行级锁InnoDB存储引擎默认使用行级锁定(Row-LevelLocking)来提高并发性能和数据一致性不可更改2.四种事务隔离级别,默认是Repeatable级别(可重复读)问题场景:脏读1.A进行了一条数据操作,但是没有提交事务,如果此时B进行这条数据的查询,是可以查......
  • 高速缓存与缓冲区
    单缓冲区双缓冲区双缓冲区可以进行全双工通信,单缓冲区只能进行半双工通信,但是要注意半双工通信也是双向的,如果题目只是笼统地说双向通信,则一定要小心循环缓冲区缓冲池高速缓存和缓冲区的对比......