最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。
环境:SpringBoot3.2.5
1. 简介
事务管理是一个至关重要的环节,它确保了数据的一致性和完整性。然而,在使用Spring框架的 @Transactional 注解时,有一个设置需要特别慎重对待,那就是事务的只读属性readOnly。
在通过 @Transactional 注解设置事务为只读事务时,你还需要注意,只读事务只支持2种事务的传播特性:REQUIRED 或 REQUIRES_NEW。
在MySQL InnoDB引擎中,所有语句都是事务,因此它们可能涉及锁定和快照等机制。然而,对于普通的查询操作,与事务协调相关的一些开销(如用事务ID标记行和其他内部结构)可能是不必要的。这正是只读事务发挥作用的地方。
貌似将事务设置为只读后性能可能会有提升!?但是在最近的一次性能测试中,我发现将 @Transactional 注解的 readOnly 属性设置为 true 后,系统的查询性能下降了约25%。结果挺意外啊。因此,在决定是否将事务设置为只读时,我们需要仔细权衡利弊。
那是不是只读事务就不要使用了呢?非也!接下来我将通过下面几方面来讲解关于只读事务的应用:
解决不可重复读问题
只读事务中进行修改操作
使用JPA时数据自动检查更新问题
读写 / 只读 事务性能测试
只读事务底层执行原理
2. 实战案例
准备环境
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
我们会通过jpa来演示上面的第二个问题,所以我们这里需要引入JPA依赖。
实体定义
public class Person {
private Integer id ;
private String name ;
private Integer age ;
// getters, setters
}
Repository定义
public interface PersonRepository extends JpaRepository<Person, Integer> {
"select p from Person p where p.id = ?1") (
Person queryById(Integer id) ;
}
自定义根据ID查询的方法,你也可以用父类的findById。
Controller测试接口
public Person queryPerson( Integer id) {
return this.personService.findById(id) ;
}
后续的测试都会基于该接口进行测试。
数据库准备数据