Spring事务一文读懂

server/2024/10/25 8:16:27/

Spring 事务详解

Spring 是 Java 开发中最流行的框架之一,它通过提供丰富的模块化功能,简化了开发流程。在复杂的企业级应用中,事务管理是至关重要的一部分,用于确保数据的一致性和完整性。在本文中,我们将深入探讨 Spring 中的事务管理,包括基本概念、事务的传播行为、事务的隔离级别、事务的回滚规则等。


1. 什么是事务?

在数据库操作中,事务是指一组操作的集合,它们要么全部成功提交,要么全部失败回滚。事务的主要目标是保证数据的一致性、可靠性和隔离性,符合数据库的 ACID 特性:

  • Atomicity(原子性):事务中的操作要么全都完成,要么全都失败。
  • Consistency(一致性):事务执行前后,数据库保持一致的状态。
  • Isolation(隔离性):事务之间相互独立执行,互不干扰。
  • Durability(持久性):事务提交后,结果是持久保存的,即使系统崩溃,数据也不会丢失。

2. Spring 事务管理的基本方式

Spring 提供了两种事务管理的方式:

  • 编程式事务管理:开发者通过代码显式地管理事务。虽然灵活,但代码耦合性较高,易出错。
  • 声明式事务管理:基于 AOP(面向切面编程)机制,通过注解或 XML 配置管理事务,简化了事务处理。

声明式事务管理是最常用的方式,它通过 @Transactional 注解,极大地简化了开发工作。


3. @Transactional 注解详解

@Transactional 是 Spring 中用于声明式事务管理的核心注解,它可以用在类或者方法上。主要有以下常用属性:

  • propagation(事务传播行为)
  • isolation(事务隔离级别)
  • timeout(超时时间)
  • readOnly(只读事务)
  • rollbackFor(指定回滚的异常类型)

我们将逐一详解这些属性。


4. 事务传播行为(Propagation)

Spring 提供了多种事务传播行为,用于定义方法在调用其他事务方法时的事务处理方式。常用的传播行为包括:

  • PROPAGATION_REQUIRED(默认):如果当前没有事务,就创建一个事务;如果当前有事务,则加入该事务。
  • PROPAGATION_REQUIRES_NEW:每次调用都会创建一个新的事务,当前事务将被挂起。
  • PROPAGATION_SUPPORTS:支持当前事务,如果没有事务,则不使用事务。
  • PROPAGATION_NOT_SUPPORTED:不使用事务,如果当前有事务则挂起当前事务。
  • PROPAGATION_MANDATORY:必须在已有事务中运行,否则抛出异常。
  • PROPAGATION_NEVER:如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前有事务,则在当前事务中嵌套事务。
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {// 事务逻辑
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {// 独立的事务逻辑
}

5. 事务隔离级别(Isolation)

事务的隔离级别用于控制多个并发事务之间的相互影响。常见的并发问题包括脏读、不可重复读和幻读。Spring 支持以下几种隔离级别:

  • ISOLATION_DEFAULT:使用数据库默认的隔离级别。
  • ISOLATION_READ_UNCOMMITTED:最低级别,允许脏读、不可重复读和幻读。
  • ISOLATION_READ_COMMITTED:防止脏读,但可能发生不可重复读和幻读(大多数数据库的默认级别)。
  • ISOLATION_REPEATABLE_READ:防止脏读和不可重复读,但可能发生幻读。
  • ISOLATION_SERIALIZABLE:最高级别,防止所有并发问题,但性能较低。
@Transactional(isolation = Isolation.READ_COMMITTED)
public void methodC() {// 使用 READ_COMMITTED 隔离级别的事务逻辑
}

6. 事务的超时(Timeout)

timeout 属性用于指定事务的超时时间,单位为秒。如果事务未能在指定时间内完成,则会自动回滚。

@Transactional(timeout = 5) // 事务超时时间为5秒
public void methodD() {// 事务逻辑
}

7. 只读事务(ReadOnly)

readOnly 属性用于指定事务是否是只读的。对于只读操作,设置 readOnly=true 可以提高性能,避免不必要的锁定。

@Transactional(readOnly = true)
public void methodE() {// 只读事务逻辑
}

8. 回滚规则(Rollback)

Spring 的默认行为是:发生未检查异常(继承自 RuntimeException 的异常)时会回滚事务,发生已检查异常(继承自 Exception 的异常)时不会回滚。我们可以通过 rollbackFornoRollbackFor 属性自定义回滚规则。

  • rollbackFor:指定哪些异常类型会触发回滚。
  • noRollbackFor:指定哪些异常类型不会触发回滚。
@Transactional(rollbackFor = Exception.class) // 指定回滚已检查异常
public void methodF() throws Exception {// 事务逻辑
}

9. 事务管理的常见问题
9.1 事务失效问题

在使用 Spring 事务时,常见的一个问题是事务注解失效。这通常发生在以下几种情况中:

  • 非 public 方法@Transactional 只能应用在 public 方法上。
  • 同类中方法互调:事务代理无法在同一类的方法中直接调用。
  • 没有使用 Spring 容器管理的类:事务只在 Spring 容器管理的 bean 上生效。
9.2 嵌套事务

当方法调用时涉及嵌套事务时,PROPAGATION_NESTED 允许在主事务中有一个子事务。如果子事务回滚,主事务不会回滚,但如果主事务回滚,则子事务也会回滚。


10. 总结

Spring 的事务管理为我们提供了强大的工具,能够轻松应对复杂的业务逻辑。通过使用声明式事务管理,我们可以灵活地配置事务的传播行为、隔离级别、回滚规则等,保证数据的一致性和完整性。Spring 事务的核心就是 @Transactional 注解,它使得开发者能够专注于业务逻辑,而不用担心底层的事务管理细节。

在实际应用中,了解事务传播、隔离级别以及如何正确处理异常,可以帮助我们构建更加健壮和高效的应用。


希望通过这篇文章,大家能对 Spring 事务管理有更加深入的理解,并在实际项目中应用这些知识!


http://www.ppmy.cn/server/122341.html

相关文章

【machine learning-15-如何判定梯度下降是否在收敛】

我们在运行梯度下降的时候,如何判定梯度下降是否在收敛呢? 梯度下降的时候,权重和偏置根据如下的公式同时更新: 程序要做的就是更新w 和 b,让梯度下降尽快的收敛,但是如何判定正在收敛呢? 方法…

Golang | Leetcode Golang题解之第420题强密码检验器

题目: 题解: func strongPasswordChecker(password string) int {hasLower, hasUpper, hasDigit : 0, 0, 0for _, ch : range password {if unicode.IsLower(ch) {hasLower 1} else if unicode.IsUpper(ch) {hasUpper 1} else if unicode.IsDigit(ch)…

【网络】高级IO——epoll版本TCP服务器初阶

目录 前言 一,epoll的三个系统调用接口 1.1.epoll_create函数 1.1.1.epoll_create函数干了什么 1.2. epoll_ctl函数 1.2.1.epoll_ctl函数函数干了什么 1.3.epoll_wait函数 1.3.1.epoll_wait到底干了什么 1.4.epoll的工作过程中内核在干什么 二,…

Vue.js与Flask/Django后端配合:构建高效Web应用

在当今的Web开发领域,前后端分离已成为一种主流的开发模式。Vue.js 作为前端框架的佼佼者,以其轻量级、响应式数据绑定和组件化的特点,受到了广大开发者的喜爱。而后端方面,Flask 和 Django 则是 Python 社区中非常流行的两个Web框…

tensorflow-dataset 内网下载 指定目录

内网下载报错 解决办法是设置环境变量,指向你的代理服务器TFDS_HTTP_PROXYhttp://xxx、TFDS_HTTPS_PROXYhttp://xxx。 留意到,赋值的是你的代理服务器,且最好协议都使用http(即使TFDS_HTTPS_PROXY也要使用http协议连服务器)。如果不这么做&a…

windows系统文件夹不显示被隐藏

是这样的,我一个U盘是老毛桃的。U盘里面有个LMT的文件夹,文件都放着,但是今天打开U盘空间占用是有的,就是不显示这个文件夹,重启进入这个PE内可以正常显示这个LMT,但是是灰色。 被改为了如下: …

人工智能开发实战照片智能搜索功能实现

内容提要 项目分析预备知识项目实战 一、项目分析 1、提出问题 随着人民生活水平的提高和手机照相功能的日趋完美,我们不经意中拍摄了很多值得回忆的时刻,一场说走就走的旅行途中也记录下许多令人心动的瞬间,不知不觉之中,我们…

yarn : 无法加载文件 C:\Users\Rog\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本

yarn : 无法加载文件 C:\Users\Rog\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本 设置命令行窗口默认以管理员身份运行,在此基础上输入以下代码,应该就好使了,切记,以下代码才是关键,我基本上…