@Transactional 是 Spring 中用于声明式事务管理的核心注解,旨在简化数据库事务操作。在传统的编程式事务中,我们需手动编写事务的开启、提交或回滚代码,而通过 @Transactional 注解将事务逻辑与业务代码解耦。
环境:SpringBoot3.4.2
1. 简介
@Transactional 是 Spring 中用于声明式事务管理的核心注解,旨在简化数据库事务操作。在传统的编程式事务中,我们需手动编写事务的开启、提交或回滚代码,而通过 @Transactional 注解将事务逻辑与业务代码解耦。只需在方法或类上添加该注解,Spring 会基于 AOP(面向切面编程)自动拦截调用,在方法执行前开启事务,执行后根据异常情况提交或回滚。这种设计显著提升了代码的可读性和可维护性。
但如果滥用@Transactional,会对系统性能产生显著负面影响,主要体现在以下几个方面:
- 过度使用会导致事务范围过大,延长数据库连接占用时间,增加锁竞争和死锁风险
- 不必要的细粒度事务会引发频繁的提交和回滚操作,加重数据库负载
- 在非关键数据操作或只读场景中滥用事务,会无谓消耗系统资源,降低整体吞吐量。
本篇文章会介绍基于 JPA 和 JDBC 时,@Transactional 注解对查询性能的影响。
纯查询到底要不要事务?
2.实战案例
2.1 准备环境
配置文件
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/batch
username: root
password: 123123
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimumIdle: 10
maximumPoolSize: 10
---
spring:
jpa:
generateDdl: false
hibernate:
ddlAuto: update
openInView: true
show-sql: false
创建实体对象
@Entity
@Table(name = "o_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id ;
private String name ;
private Integer age ;
private String phone ;
private String sex ;
// getters, setters
}
准备接口
@GetMapping("")
public ResponseEntity<?> query() {
return ResponseEntity.ok(this.userService.queryUser()) ;
}
准备数据(500w)

图片
2.1 使用Repository查询测试
测试1,不使用@Transactional注解
private final UserRepository userRepository ;
public User queryUser() {
return this.userRepository.findById(4888888).orElse(null) ;
}
使用JMeter测试结果如下:

吞吐量平均:9700
测试2,使用@Transactional
@Transactional
public User queryUser() {}
使用JMeter测试结果如下:

吞吐量平均:12700
这是否打破了你原有的认知呢?按照常规理论,使用 @Transactional 注解通常会使性能变差,然而当前呈现的数据却表明,使用该注解后性能反而有所提升。
测试3,使用只读事务
@Transactional(readOnly = true)
public User queryUser() {}
使用JMeter测试结果如下:

吞吐量平均:9300
该结果与不使用注解相差不大。
思考:为什么使用了@Transactional注解反而性能更高呢?欢迎大家留言讨论。
2.3 使用JDBC查询
测试1,不使用@Transactional注解
private final JdbcTemplate jdbcTemplate ;
public User queryUser() {
return this.jdbcTemplate.queryForObject("select id, name, age, phone, sex from o_user where id = 4888888", new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User() ;
user.setId(rs.getInt("id")) ;
user.setAge(rs.getInt("age")) ;
user.setName(rs.getString("name")) ;
user.setPhone(rs.getString("phone")) ;
user.setSex(rs.getString("sex")) ;
return user ;
}
}) ;
}
JMeter测试结果:

吞吐量平均:25000
JPA是简单了,代价就是性能太差了。
测试2,使用@Transactional注解
@Transactional
public User queryUser() {}
JMeter测试结果:

吞吐量平均:13100
这倒是符合我们的预期,使用了@Transactional注解性能明显下降。
测试3,使用只读事务
@Transactional(readOnly = true)
public User queryUser() {}
JMeter测试结果:

同样符合预期,与读写事务差不多。
2.4 使用EntityManager查询
测试1,不使用@Transactional注解
private final EntityManager em ;
public User queryUser() {
return this.em.find(User.class, 4888888) ;
}
JMeter测试结果:

吞吐量平均:24000
测试2,使用@Transactional注解
@Transactional
public User queryUser() {
return this.em.find(User.class, 4888888) ;
}
JMeter测试结果:

图片
吞吐量平均:13000
测试3,使用只读事务
@Transactional(readOnly = true)
public User queryUser() {}
JMeter测试结果:

图片
吞吐量平均:9800
2.5 性能柱状图

图片
2.6 查询使用事务总结
- 保证一致性:在一个事务中,所有查询看到的是同一时间点的数据快照(取决于隔离级别),避免了中途数据被其他事务修改导致的不一致
- 性能优化:Spring 提供 @Transactional(readOnly = true),明确标记为只读事务。这可以让底层数据库(如 Oracle、MySQL InnoDB)进行优化,例如启用只读快照、减少锁竞争等。
- 连接复用:在一个事务中的多个操作可以复用同一个数据库连接,减少连接创建/释放开销。
- 与写操作兼容:如果将来该查询方法被包含在一个更大的写事务中,有 @Transactional 可以无缝集成。
如下多个查询使用事务保证了同一时间点的数据:
private final UserRepository userRepository ;
private final OrderRepository orderRepository ;
@Transactional(readOnly = true)
public UserInfoDto getUserInfo(Long userId) {
User user = userRepository.findById(userId);
List<Order> orders = orderRepository.findByUserId(userId);
return new UserInfoDto(user, orders);
}
AI大模型学习福利
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量
1076

被折叠的 条评论
为什么被折叠?



