@Transactional用错!严重影响性能,Spring Boot 事务最佳实践

文摘   2024-12-22 10:01   新疆  

Spring Boot 3实战案例合集》现已囊括超过60篇精选实战文章,并且此合集承诺将永久持续更新,为您带来最前沿的技术资讯与实践经验。欢迎积极订阅,享受不断升级的知识盛宴!订阅用户将特别获赠合集内所有文章的最终版MD文档(详尽学习笔记),以及完整的项目源码,助您在学习道路上畅通无阻。

环境:SpringBoot3.2.5



1. 简介

在任何应用程序中,事务管理都至关重要,特别是在基于Spring的应用程序中,它在确保数据完整性和一致性方面发挥着核心作用。以下是在Spring环境中有效管理事务的一些最佳实践:

使用声明式事务管理:
Spring提供了编程式和声明式两种事务管理方式。通常更推荐使用声明式管理,即使用@Transactional等注解,因为它可以使代码更简洁,并将事务管理与业务逻辑分开。如下示例:

@Servicepublic class StudentService {
  private final StudentRepository studentRepository ;  public ProductService(StudentRepository studentRepository) {    this.studentRepository = studentRepository ; }
@Transactional public void updateStudentSno(Long id, String sno) {    studentRepository.findById(id)     .ifPresent(student-> {        student.setSno(sno) ;     }) ; }}

在上面的示例中 updateStudentSno 方法被 @Transactional 注解标记,表明它应该在事务内执行。在该方法内部,我们根据 id 获取 Student 实体,更新其学号,当事务提交时会自动检查当前的实体是否发生变化,如果变化则自动保存。如果在执行该方法期间发生任何异常,事务将回滚,以确保数据一致性。

Hibernate: select s1_0.id,s1_0.name,s1_0.sno,s1_0.version from t_student s1_0 where s1_0.id=?Hibernate: update t_student set name=?,sno=?,version=? where id=? and version=?

我们并没有做更新动作,底层会自动检查。注意:你必须在一个事务中才会自动检查更新,否则不会。

接下来,我们将介绍在Spring中使用事务时务必注意事项,以下是本篇文章介绍的内容:

  • 控制事务的执行尽可能的简短

  • 正确选择合适的事务隔离级别

  • 不要在事务中处理与事务无关的任何事

  • 考虑事务中异常的处理

  • 优化与数据库的交互,减少应用与数据库的交换次数

  • 合理应用锁机制(乐观锁、悲观锁)

  • 处理事务的并发相关的问题


2. 最佳实践

2.1 保持事务简短且简单

事务应仅包含必要的操作。长时间运行的事务可能会导致资源争用、增加死锁的可能性以及性能下降。应尽可能缩小事务的范围。如下示例(上面示例):

@Transactionalpublic void updateStudentSno(Long id, String sno) {  studentRepository.findById(id)    .ifPresent(student-> {      student.setSno(sno) ;    }) ;}
  • updateStudentSno 方法被 @Transactional 注解标记,表明它应该在事务内执行。

  • 在该方法内部,它根据ID检索Student,更新其学号,最终事务提交时自动更新。

  • 该事务仅包含更新所必需的操作,保持简短且专注于数据操作。

  • 通过遵循这种方法,可以最大限度地缩短事务持续时间,从而降低资源争用、死锁或性能下降的风险。

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章