目录
- 前言
- 1. 基本知识
- 2. 性能对比
前言
对于Java的基本知识推荐阅读:
- java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
- 【Java项目】实战CRUD的功能整理(持续更新)
而对于@Transactional的基本知识可看我之前的科普:
- 详细分析Java中的@Transactional注解
- 出现 Transaction rolled back because it has been marked as rollback-only 解决方法
1. 基本知识
@Transactional(readOnly = true) 是 Spring 框架中的一个注解,通常用于标记只读事务
所标注的方法或类中的所有数据库操作都是只读的,不会进行数据的修改操作,主要目的是优化事务处理,提高性能
基本的作用如下:
- 优化性能:在只读事务中,数据库可以进行一些优化,例如避免脏数据检查,提高读取速度
- 防止数据修改:显式声明只读事务,帮助开发人员和维护人员明确意图,防止误操作导致数据修改
- 资源管理:在某些数据库系统中,只读事务可能会减少锁的竞争,提升并发性能
但是不可执行修改操作,而且在众多事务的情况下,如果有Bug,可能会多少影响事务,导致一直重试
2. 性能对比
对于大数据量的查询,可以大大优化查询速度(因个人项目而已,加之前最好也测试下效果明显不)
@Service
public class MyService {@Autowiredprivate MyRepository myRepository;@Transactional(readOnly = true)public List<MyEntity> getEntitiesReadOnly() {long startTime = System.currentTimeMillis();List<MyEntity> entities = myRepository.findAll();long endTime = System.currentTimeMillis();System.out.println("Read-only Transaction Time: " + (endTime - startTime) + " ms");return entities;}@Transactionalpublic List<MyEntity> getEntitiesReadWrite() {long startTime = System.currentTimeMillis();List<MyEntity> entities = myRepository.findAll();long endTime = System.currentTimeMillis();System.out.println("Read-write Transaction Time: " + (endTime - startTime) + " ms");return entities;}
}
理论的只读事务会比读写事务执行时间大大减少,但是实操发现波动不是很大,可能我的这个数据量不是很大
还有一个需要注意的点,如果服务层中有大量计算的数据,会让其长时间保持数据库链接,导致数据库链接匮乏
基本的规则以及注意事项如下:
- 适用于只读操作:只在不涉及数据修改的操作上使用 @Transactional(readOnly = true)
- 搭配缓存:结合缓存机制,可以进一步提升性能
- 标记在类或方法上:可以标记在整个类上,表示类中所有方法都是只读的,也可以单独标记在方法上
注意点
谨慎使用嵌套事务:在使用嵌套事务时要小心,避免只读事务嵌套读写事务,导致意外问题。
防止误用:确保只读事务中不包含任何数据修改操作,否则会抛出异常。