Spring中@Transactional注解

在Spring框架中,@Transactional 是一个注解,用于声明事务性的方法。这个注解可以被应用在方法级别或类级别上。它提供了一种声明式的事务管理方式,避免了在代码中直接编写事务管理相关的代码。@Transactional 注解能够将一个方法纳入到一个事务中,使其成为一个事务性方法。

以下是 @Transactional 注解的一些关键属性和用法:

关键属性和用法

1. Propagation(传播行为):

  • 定义了事务方法的执行期间,当前事务传播到被调用的方法。
  • 常用的传播行为包括 REQUIRED(如果有事务,则加入;没有事务,则新建一个)和 REQUIRES_NEW(每次都新建一个事务,挂起当前事务)。
@Transactional(propagation = Propagation.REQUIRED)
public void transactionalMethod() {// 方法体
}

2. Isolation(隔离级别):

  • 定义了事务的隔离级别,即多个事务并发执行时,事务之间的隔离程度。
  • 常用的隔离级别包括 READ_COMMITTED(允许读取已提交的数据,避免脏读)和 SERIALIZABLE(最高的隔离级别,保证事务的完全隔离)。
@Transactional(isolation = Isolation.READ_COMMITTED)
public void transactionalMethod() {// 方法体
}

3. ReadOnly(只读):

  • 指定事务是否为只读事务。如果设置为 true,则表示这个事务只读取数据但不更新数据,可以提高事务的性能。
@Transactional(readOnly = true)
public void readOnlyTransactionalMethod() {// 方法体
}

4. Timeout(超时):

  • 定义了事务的超时时间,即事务方法的执行时间超过了这个值,事务将被回滚。
@Transactional(timeout = 60) // 60 秒超时
public void transactionalMethod() {// 方法体
}

5. RollbackFor(回滚异常):

  • 指定哪些异常触发事务回滚。可以指定多个异常类型。
@Transactional(rollbackFor = {SQLException.class, IOException.class})
public void transactionalMethod() throws SQLException, IOException {// 方法体
}

6. NoRollbackFor(不回滚异常):

  • 指定哪些异常不触发事务回滚。同样可以指定多个异常类型。
@Transactional(noRollbackFor = BusinessException.class)
public void transactionalMethod() throws BusinessException {// 方法体
}

使用方法:

  1. 在类级别使用 @Transactional

    @Service
    @Transactional
    public class MyService {// 方法
    }
    
  2. 在方法级别使用 @Transactional

    @Service
    public class MyService {@Transactionalpublic void myTransactionalMethod() {// 方法体}
    }
    

事务回滚

事务回滚是指在事务执行过程中发生了某些错误或异常,系统会撤销当前事务的所有操作,使数据回滚到事务开始之前的状态
事务回滚的作用是确保事务的一致性和完整性。如果在事务中发生了错误,事务回滚可以防止数据的部分更新,确保数据库的一致性。

何时会触发事务回滚:

  1. Unchecked 异常: 默认情况下,Spring @Transactional 注解只会在遇到未检查(unchecked)异常时触发事务回滚。未检查异常是指继承自 RuntimeException 的异常,如 NullPointerExceptionArithmeticException 等。

    @Transactional
    public void transactionalMethod() {// 发生未检查异常时,事务将回滚throw new RuntimeException("Something went wrong");
    }
    
  2. 指定回滚条件: 通过 rollbackFornoRollbackFor 属性,可以在 @Transactional 注解上指定哪些异常触发事务回滚或不触发事务回滚。

    @Transactional(rollbackFor = {SQLException.class, IOException.class})
    public void transactionalMethod() throws SQLException, IOException {// 发生指定异常时,事务将回滚throw new SQLException("Database error");
    }
    
  3. Checked 异常: 如果需要回滚事务的是受检查的异常(checked exception),可以使用 @Transactional(rollbackFor = Exception.class),但这并不是通常的做法,因为通常情况下事务回滚更关注未检查异常。

  • @Transactional(rollbackFor = Exception.class) 表示在使用 Spring 的声明式事务管理时,如果发生任何 Exception 及其子类的异常,都会导致事务回滚。这意味着如果在被注解的方法中抛出了任何 Exception,不管是 checked 还是 unchecked 异常,都会触发事务回滚。
  • 这种设置的意义在于,有时候我们可能希望对于某些异常情况,即便是 checked 异常,也触发事务回滚。通常情况下,Spring 默认只对未检查异常(RuntimeException 及其子类)进行回滚。通过设置 rollbackFor = Exception.class,我们扩大了回滚的范围,即使是 checked 异常也会导致事务回滚。

例子:

@Transactional(rollbackFor = Exception.class)
public void transactionalMethod() throws CustomCheckedException {// 操作数据库// 抛出 checked 异常,事务将回滚throw new CustomCheckedException("Custom checked exception");
}

在上述例子中,即使 CustomCheckedException 是一个 checked 异常,由于设置了 rollbackFor = Exception.class,这个方法抛出的异常也会导致事务回滚。

需要注意的是,过度使用这样的设置可能会导致意外的结果,因为某些 checked 异常可能是可以被业务逻辑处理的。因此,一般来说,建议在 rollbackFor 中指定具体的异常类型,而不是将其设置为 Exception.class

回滚的意义:

  1. 一致性: 在事务中的一组操作,要么全部执行,要么全部不执行。回滚确保了数据的一致性。
  2. 完整性: 回滚可以防止数据的部分更新,保证了数据库的完整性。
  3. 可靠性: 当出现异常或错误时,回滚确保了系统的可靠性,避免了数据不一致或丢失。

与 try-catch 的关系:

在事务性方法中,通常不需要显式地使用 try-catch 块来捕获异常,因为 Spring 会在检测到未检查异常时触发事务回滚。如果在事务性方法中使用了 try-catch 块,并成功捕获了异常,Spring 将不会触发事务回滚。在这种情况下,你可以手动调用 setRollbackOnly 方法来指示事务回滚。

@Transactional
public void transactionalMethod() {try {// 操作数据库} catch (Exception e) {// 捕获异常,不触发事务回滚// 手动指示事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}
}

@Transactional 没有抛出异常时是否管用:

如果 @Transactional 注解所标注的方法没有抛出未检查异常,并且方法成功完成,那么事务会正常提交,而不会回滚。@Transactional 不仅用于处理异常,还用于确保事务的一致性,即一组操作要么全部成功,要么全部失败。在没有异常抛出的情况下,@Transactional 也能够确保事务的完整性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/191537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM的生鲜在线销售系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

亚马逊云科技推出新一代自研芯片

北京——2023 年12月1日 亚马逊云科技在2023 re:Invent全球大会上宣布其自研芯片家族的两个系列推出新一代,包括Amazon Graviton4和Amazon Trainium2,为机器学习(ML)训练和生成式人工智能(AI)应用等广泛的工…

Linux: 退出vim编辑模式

一、使用快捷键进行退出 1、按“Esc”键进入命令模式 当我们在vim编辑模式下输入完毕需要进行退出操作时,首先需要按下“Esc”键,将vim编辑器从插入模式或者替换模式切换到命令模式。 ESC 2、输入“:wq”保存并退出 在命令模式下,输入“:…

锐捷RG-UAC应用网关 前台RCE漏洞复现

0x01 产品简介 锐捷RG-UAC系列应用管理网关是锐捷自主研发的应用管理产品。 0x02 漏洞概述 锐捷RG-UAC应用管理网关 nmc_sync.php 接口处存在命令执行漏洞,未经身份认证的攻击者可执行任意命令控制服务器权限。 0x03 复现环境 FOFA:app"Ruijie-R…

JavaWeb | JavaScript基础

目录: 1.JavaScript简介2.JavaScript注释3.JavaScript语法 :变量的定义函数的定义 4.JavaScript内置对象4.1 window的作用 :出现提示框打开关闭窗口定时器 4.2 history的作用4.3 document的作用 :在网页上输出设置网页属性访问文档元素,特别是…

jni子线程回调java实例

背景 最近有项目需求,需要在jni中创建多个子线程,并在子线程中,回调java将byte[]数据上报给java处理 demo实例 关键代码 static jmethodID method_callback; jclass global_class NULL; jclass myClass NULL; JavaVM* gJavaVM NULL;ji…

6.8 Windows驱动开发:内核枚举Registry注册表回调

在笔者上一篇文章《内核枚举LoadImage映像回调》中LyShark教大家实现了枚举系统回调中的LoadImage通知消息,本章将实现对Registry注册表通知消息的枚举,与LoadImage消息不同Registry消息不需要解密只要找到CallbackListHead消息回调链表头并解析为_CM_NO…

基于Java SSM人才市场管理系统

随着人才流动的正常化以及大专院校毕业生就业人数的增长,人才市场的业务越来越红火。人才市场管理系统实现对人才市场业务的规范化管理。系统主要管理的信息及操作如下: 用人单位:编号、名称、联系人、电话、招聘人数、学历要求、职称要求。 …

【Java面试——基础题】

Java基础部分,包括语法基础,泛型,注解,异常,反射和其它(如SPI机制等)。 1.1 语法基础 面向对象特性? 封装 利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成…

kubelet漏洞CVE-2020-8559复现与分析

首先下载源码 git clone --branch v1.17.1 --single-branch https://github.com/kubernetes/kubernetes.git 参考 移花接木:看CVE-2020-8559如何逆袭获取集群权限-腾讯云开发者社区-腾讯云

React Router(用法介绍)

React Router 是一个用于在 React 应用中处理路由的库。它允许你定义应用程序中的多个页面,并在 URL 改变时显示不同的内容。 要使用 React Router,你需要首先安装它: npm install react-router-dom然后,在你的应用中引入所需的…

一些小笔记(Delphi)

工具:Delphi10.4 用Delphi写了一个解析json文件的小程序, 需求是能解析整个文件夹中的所有文件,也能只解析某一个文件,文件或者文件夹的路径能够直接填写,也能够通过选择的方式去填充。 我的解决办法如下&#xff1…

12-1 Springboot过滤拦截和日志处理

Springboot的日志 默认日志框架:logback 1.日志以文件的形式的保存 使用logback框架 ->(运行日志,开发中用于调式的,在开发中作为系统运行日志记录故障,从而追究问题根源) 2.日志相关的表 记录用户相关操作信息 -> 需要我…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(2)》(18)

《Linux操作系统原理分析之linux存储管理(1)》(17) 6 Linux存储管理6.2 选段符与段描述符6.2.1 选段符6.2.2 段描述符6.2.3 分段机制的存储保护 6.3 80x86 的分页机制6.3.180x86 的分页机制6.3.2 分页机制的地址转换6.3.3 页表目录…

PTA预编译中的宏定义:求平行四边形面积

已知平行四边形面积函数的原型如下: 函数原型 double ParaArea(double base, double height); 说明:参数 base 和 height 分别为平行四边形的底和高,函数值为平行四边形的面积。 请在空白处填写适当内容,用带参数的宏替换命令…

FWFT-FIFO的同步和异步verilog代码

//----------------------------------------------------------------------------- // File Name : fifo_sync.v //----------------------------------------------------------------------------- //参数化同步FIFO。DEPTH可以是任何大于0的整数值。实际使用的内存深度是…

嵌入式WIFI芯片通过lwip获取心知天气实时天气信息(包含完整代码)

一、天气API 1. 心知天气的产品简介 HyperData 是心知天气的高精度气象数据产品,通过标准的 Restful API 接口,提供标准化的数据访问。无论是 APP、智能硬件还是企业级系统都可以轻松接入心知的精细化天气数据。 HyperData API V4版是当前的最新…

运筹学-使用python建模基本操作

运筹学中的python基本操作 运筹学库的基本介绍MIP 库的使用networkx 库的使用运筹学 所谓运筹学(Operation Research) 就是用数学方法研究各种系统最优化问题的学科,为决策者提供科学决策的依据,求解系统最优化问题,制定合理运用人力,物力,财力的方案。 库的基本介绍 对…

Go函数和方法之间有什么区别

基础知识 在了解两者不同之前,还是简单的回顾一下基础语法知识。下面的实例,定义一个函数和方法,然后调用函数和方法。 package mainimport "fmt"// 函数和方法 func function1() {fmt.Println("我是一个名字叫做function1的…

要致富 先撸树——判断循环语句(六)

引子 什么?万年丕更的作者更新了? 没错!而且我们不当标题党,我决定把《我的世界》串进文章里。 什么?你不玩《我的世界》? 木有关系 本专栏文章主要在讲c语言的语法点和知识,保证让不玩《我…