详细分析Java中的@Transactional注解

目录

  • 前言
  • 1. 基本知识
  • 2. 常用属性
  • 3. Demo
  • 4. 总结

前言

@Transactional 是 Spring 框架中用于管理事务的注解。

  1. 该注解来源于Spring,对于Spring的基础知识可看我之前的文章:
    Spring框架从入门到学精(全)

  2. 该注解也可用在xxl-job框架中,让事务进行回滚执行,可看我之前的文章:
    详细分析Java中的分布式任务调度框架 XXL-Job

  3. 涉及的事务相关知识可参考之前这篇文章:
    数据库关于事务的详解分析(全)包含面试常问的细节

1. 基本知识

@Transactional 注解用于标记一个方法或类需要被 Spring 托管的事务管理。

它可以应用于类级别的和方法级别的,用于控制事务的行为。

作用优点缺点
1.事务管理: 该注解确保被注解的方法或类在执行时将被包装在一个事务中。

2.事务传播: 它定义了在嵌套调用中,新事务是如何与现有事务交互的。
1.简化事务管理: 通过注解方式,简化了对事务的管理,不再需要手动编写事务相关的代码。

2.减少样板代码: 提供了一种声明式的方式,减少了样板式的事务管理代码。
过度使用可能导致性能问题: 在某些情况下,过度使用事务注解可能导致性能下降,因为每个被注解的方法都会被包装在一个事务中。

对于@Transactional注解有好些属性,可通过源码查看:

在这里插入图片描述

2. 常用属性

常用的属性主要如下:

一、propagation: 事务的传播行为,默认值是 REQUIRED

常用的取值包括:

  • REQUIRED:如果当前存在事务,则加入该事务;否则,创建一个新事务。
  • REQUIRES_NEW:创建一个新的事务,并挂起当前事务(如果存在)。
  • SUPPORTS:支持当前事务,如果没有事务,则以非事务方式执行。
  • MANDATORY:强制要求存在当前事务,如果不存在,则抛出异常

示例代码如下:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodWithNewTransaction() {// ...
}

二、isolation: 事务的隔离级别,默认是 DEFAULT

常用的取值包括:

  • DEFAULT:使用数据库默认的隔离级别。
  • READ_UNCOMMITTED:允许读取未提交的数据更改。
  • READ_COMMITTED:只能读取已提交的数据更改。
  • REPEATABLE_READ:可重复读,确保在同一事务中对相同数据的多次读取是一致的。
  • SERIALIZABLE:最高隔离级别,确保在同一事务中对相同数据的多次读取和写入都是一致的。

示例代码如下:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void methodWithCustomIsolationLevel() {// ...
}

三、readOnly: 指定事务是否为只读,默认值为 false。
如果设置为 true,表示只读事务,不允许有写操作。

@Transactional(readOnly = true)
public void readOnlyMethod() {// ...
}

四、timeout: 指定事务超时时间,单位为秒。
如果事务执行时间超过设定的超时时间,将回滚事务。

@Transactional(timeout = 30)
public void methodWithTimeout() {// ...
}

五、rollbackFor 和 noRollbackFor: 指定在哪些异常情况下回滚事务或不回滚事务。

@Transactional(rollbackFor = CustomException.class)
public void methodWithRollbackForException() {// ...
}@Transactional(noRollbackFor = AnotherException.class)
public void methodWithNoRollbackForException() {// ...
}

这些是 @Transactional 注解中一些常用的属性。通过设置这些属性,你可以根据具体需求调整事务的行为。

3. Demo

假设有一个简单的银行应用,有两个服务类,一个是转账服务 TransferService,另一个是用户服务 UserService。

确保转账和更新用户余额这两个操作在同一个事务中。

代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class TransferService {@Autowiredprivate UserService userService;@Transactionalpublic void transferMoney(String fromAccount, String toAccount, double amount) {// 扣除转账账户余额userService.decreaseBalance(fromAccount, amount);// 增加接收账户余额userService.increaseBalance(toAccount, amount);}
}

以及

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactionalpublic void decreaseBalance(String account, double amount) {// 扣除余额的数据库更新操作// ...}@Transactionalpublic void increaseBalance(String account, double amount) {// 增加余额的数据库更新操作// ...}
}

在上述示例中,@Transactional 注解确保了 transferMoney 方法和 decreaseBalance、increaseBalance 方法都在同一个事务中执行。

如果其中任何一个方法发生异常,整个事务将回滚。

对于实际的应用场景,一个rollbackFor也可:@Transactional(rollbackFor = Exception.class)
具体如下:
在这里插入图片描述

也可配合XXL-Job的框架进行使用,主要如下:

在这里插入图片描述

4. 总结

对应的场景案例可看这篇文章(个人感觉不错):spring中@Transactional注解的作用,使用场景举例

  1. @Transactional 注解只能用在public 方法上,private以及protected不会报错,但不会生效
  2. 该注解只有在spring容器中扫描到才生效
  3. 可以用在类上或者方法上,范围不一致而已
  4. 如果使用了try catch,注解会失效。(虽然只能回滚非检查型异常,具体为RuntimeException及其子类和Error子类,但要想捕获可以尝试加入@Transactional(rollbackFor = Exception.class)
  5. 非事务方法调用事务方法,要用代理对象调用否则事务会失效。而事务方法调用非事务不会失效。

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

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

相关文章

自动化测试框架pytest系列之8个常用的装饰器函数

自动化测试框架pytest系列之基础概念介绍(一)-CSDN博客 自动化测试框架pytest系列之21个命令行参数介绍(二)-CSDN博客 自动化测试框架pytest系列之强大的fixture功能,为什么fixture强大?一文拆解它的功能参数。(三)-CSDN博客 接上文 3.5 pytest的8…

Vant4在Vue3.3中如何按需导入组件和样式

前言 最近我在Vue 3.3的项目中对Vant4做按需导入时,尽管按照Vant4的官方指南进行操作,但样式仍然无法正确加载。经过深入研究和多篇文章的比较,我终于找到了在Vue3中如何正确的按需导入Vant 4组件和样式的方法。由于Vue3.3和Vant4相对较新&am…

多无人机编队避障(人工势场法)

matlab2020正常运行,预设编队类型,目标位置,障碍物 多无人机编队避障(人工势场法)资源-CSDN文库

浅析链表结构

一、单向链表 C语言中数组是常用的一种数据类型,但可惜数组长度是固定大小的,不能动态扩展,使用起来有时不是很方便。然后就有了自定义的动态数组结构,动态数组就比较好用了,长度可以任意扩展,但还有一个问…

easyexcel 3.0.x 版本实现指定列 锁定以及指定列隐藏

1:效果示例 2:代码示例: UnLockCell.java package com.example.juc.zhujie;/*** Author * Date Created in 2023/12/19 10:09* DESCRIPTION:* Version V1.0*/import java.lang.annotation.*;/*** 用于标记锁定哪些列不需要锁定* author 12…

【LangChain学习之旅】—(7) 调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM?

【LangChain学习之旅】—(7) 调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM? 大语言模型发展史预训练 微调的模式用 HuggingFace 跑开源模型申请使用 Meta 的 Llama2 模型通过 HuggingFace 调用 LlamaLangChain 和 Hugging…

若依在表格中如何将字典的键值转为中文

文章目录 一、需求:二、问题解决步骤1、给需要转换的列绑定formatter属性2、获取字典项3、编写formatter属性绑定的方法 一、需求: 后端有时候返回的是字典的键值,在前端展示时需要转成中文值 后端返回的是dictValue,现在要转换…

【Git】本地仓库文件的创建、修改和删除

目录 一、基本信息设置 1、设置用户名2、设置用户名邮箱 二、Git仓库操作介绍 1、创建一个新的文件夹2、在文件内初始化git仓库(创建git仓库)3、向仓库中添加文件 1.创建一个文件2.将文件添加到暂存区3.将暂存区添加到仓库 4、修改仓库文件 1.修改文件2.…

java中数组

文章目录 java中数组思维导图数组数组概念 数组定义格式详解数组的访问 常见异常数组索引值越界异常:ArrayIndexOutOfBoundsException空指针异常:NullPointerException 案例例一打印A-Z和0-9例二数组转置输出 java中数组 思维导图 数组 数组概念 组就…

Java8常用新特性

目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 简介 Java 8是Java编程语言的一个重要版本,引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧&#…

Mac 下载 nvm 后执行nvm -v 命令报错 nvm: command not found

1、问题:Mac 使用命令下载nvm 成功后执行 nvm -v 查看,报错:nvm command not found 2、原因:可能是系统更新后,默认的 shell 是 zsh,所以找不到配置文件 3、解决:可添加编辑.bash_profile 和 …

Docker 安装部署

1、Docker 安装 ① 卸载docker,清空之前的docker文件 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce…

Spring Boot - Application Events 的发布顺序_ContextRefreshedListener

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的,它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#…

2024年最新软件测试面试题

Part1 1、你的测试职业发展是什么?【文末有面试文档免费领取】 测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年积累测试经验,按如何做…

Python——猜猜心里的数字(2)

1、数字随机产生,范围1-10 2、有三次机会猜数字通过三层嵌套 3、每次猜不中,提示大小 import random numrandom.randint(1,10) guess_num int(input("请输入您猜测的值:")) if guess_numnum:print("恭喜你,第一次…

【漏洞复现】Office365-Indexs-任意文件读取

漏洞描述 Office 365 Indexs接口存在一个任意文件读取漏洞,攻击者可以通过构造精心设计的请求,成功利用漏洞读取服务器上的任意文件,包括敏感系统文件和应用程序配置文件等。通过利用此漏洞,攻击者可能获得系统内的敏感信息,导致潜在的信息泄露风险 免责声明 技术文章…

LLM之长度外推(二)| Self-Extend:无需微调的自扩展大模型上下文窗口

论文链接:https://simg.baai.ac.cn/paperfile/a34ae7f4-f0ce-4f8f-b8f2-e8e4d84bbee5.pdf 目前大模型基本都采用transformer结构,而transformer中attention机制的计算复杂度与序列长度呈平方关系,因此大模型在训练时候通常会设置固定的上下文…

案例117:基于微信小程序的新闻资讯系统设计与实现

文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder …

学习Vue封装的过渡与动画总结

今天学习了Vue封装的过渡与动画&#xff0c;接下来说一下Vue是如何实现的&#xff0c;首先原生的方法是在style元素中给指定元素添加过渡的过渡或动画&#xff0c;但Vue就不需要直接获取到需要过渡或动画的元素&#xff0c;而是使用一个<transition>的标签来包裹住想要过…

py的函数讲解

前言:本章节我们来讲函数&#xff0c;主播略微感觉到有点小难&#xff0c;友友们需要认真看 目录 一.初始函数 1.1关于函数 1.2举例 1.3小结 二.函数的基础语法 2.1关于函数的语法 2.2举例 2.3小结 三.函数的参数 3.1关于函数的参数 3.2举例 3.3小结 四.函数的返回…