👉这是一个或许对你有用的社群

🐱一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料:

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21+ SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本

来源:medium.com 丛林(Java知音)


今天,我想谈谈 Spring 提供的@Transactional(readOnly = true)

之所以聊这个是因为我公司项目的代码里有很多@Transactional(readOnly = true),用过的同学都说@Transactional(readOnly = true)提高了性能。先思考以下几点:

  • @Transactional(readOnly = true)是如何工作的,为什么使用它可以提高性能?
  • 当我们使用 JPA 时,是否应该总是将@Transactional(readOnly = true)添加到服务层的只读方法?有什么取舍吗?

在开始之前,我们使用 Hibernate 来实现 JPA。

1. @Transactional(readOnly = true)是如何工作的,为什么使用它可以提高性能?

首先,让我们看一下事务接口。

activeConnections:0,IdleConnections:10,TotalConnections:10starttransactionalReadOnlyOnRepository!!Hibernate:selectu1_0.id,u1_0.email,u1_0.name,u1_0.profile_file_namefromusersu1_0activeConnections:0,IdleConnections:10,TotalConnections:10activeConnections:0,IdleConnections:10,TotalConnections:10activeConnections:0,IdleConnections:10,TotalConnections:10activeConnections:0,IdleConnections:10,TotalConnections:10activeConnections:0,IdleConnections:10,TotalConnections:10endtransactionalReadOnlyOnRepository!!activeConnections:0,IdleConnections:10,TotalConnections:10

正如您所看到的,@Transactional(readOnly = true)一旦查询结果到达,存储库层就会释放连接。

然而,@Transactional(readOnly = true)在服务层的方法中直到服务层的方法结束才释放连接。

因此,当服务层的方法有需要大量时间的逻辑时要小心,因为它可以长时间持有数据库连接,这可能会导致数据库连接匮乏。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

3. 回顾

很明显,@Transactional(readOnly = true)有很多优点。

  • 性能改进:只读实体不进行脏检查
  • 节省内存:不维护持久状态的快照
  • 数据一致性:只读实体的更改不会持久化
  • 当我们使用主从或读写副本集(或集群)时,@Transactional(readOnly = true)使我们能够连接到只读数据库

但是,您还应该记住,@Transactional(readOnly = true)在服务层的方法中可能会导致数据库死锁、性能低下和数据库连接匮乏!

当您需要将只读查询仅仅作为一个事务执行时,请毫不犹豫选择的在服务层的方法中使用@Transactional(readOnly = true),如果你的服务层的方法中有大量其他逻辑方法时,就要做取舍了!


欢迎加入我的知识星球,全面提升技术能力。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

本篇文章来源于微信公众号: Java基基



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2024-08-02