Spring 注解 @Transactiona

@Transactional 是什么

@Transactional 是一个用于声明事务性操作的注解,通常用于 Java 编程语言中的 Spring 框架中。这个注解被用来标记一个方法或类需要被事务管理器事务化的地方。

在 Spring 中,事务是用于管理数据库操作的机制,确保一系列操作要么全部成功提交,要么全部回滚到事务开始的状态。@Transactional 注解可以应用在类级别和方法级别。当应用在类级别时,所有类中的方法都会受到事务管理;当应用在方法级别时,只有被标记的方法会受到事务管理。

这个注解提供了一些属性,允许你指定事务的传播行为、隔离级别、超时时间等。通过使用 @Transactional,你可以简化事务管理的配置,使得代码更加清晰和易于维护。

@Transactional 怎么用

@Transactional 注解可以用于方法级别或类级别,具体取决于你想要在哪个范围内应用事务管理。以下是一些示例用法:

方法级别的使用:

import org.springframework.transaction.annotation.Transactional;@Service
public class MyService {@Transactionalpublic void myTransactionalMethod() {// 这里是需要进行事务管理的业务逻辑}
}

在上面的例子中,myTransactionalMethod 方法被 @Transactional 注解标记,这表示这个方法需要在事务管理下运行。当方法执行时,如果发生异常,事务将回滚;否则,事务将提交。

类级别的使用:

import org.springframework.transaction.annotation.Transactional;@Service
@Transactional
public class MyService {public void myMethod() {// 这里是需要进行事务管理的业务逻辑}
}

在这个例子中,整个 MyService 类都受到 @Transactional 注解的影响。任何在这个类中被调用的方法都将在事务管理下运行。

你还可以使用 @Transactional 注解的属性来自定义事务的一些特性。例如:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, timeout = 300)
public void myTransactionalMethod() {// 业务逻辑
}

这里,propagation 指定事务的传播行为,isolation 指定隔离级别,readOnly 指定是否为只读事务,timeout 指定事务超时时间(单位为秒)。

确保你的类或方法被 Spring 托管(例如使用 @Service@Component 等注解),以便 Spring 能够识别并应用 @Transactional 注解。

@Transactional 有什么优点

使用 @Transactional 注解带来了一些优点,使得事务管理更加方便和灵活:

  1. 简化事务管理配置: @Transactional 注解允许你在方法或类级别声明事务性操作,从而简化了事务管理的配置。你不再需要显式地在配置文件中声明事务管理器和事务属性,而是可以直接在代码中使用注解。

  2. 提高代码可读性: 将事务性操作直接标记在方法上,使得代码更加清晰和易于理解。通过注解,你可以一目了然地知道哪些方法是需要在事务管理下运行的。

  3. 灵活的事务属性配置: @Transactional 注解提供了一些属性,如传播行为、隔离级别、只读事务等,使得你可以根据具体需求灵活配置事务的行为。这使得在不同的业务场景下能够采用不同的事务属性。

  4. 运行时异常触发回滚: 默认情况下,@Transactional 注解会将未捕获的运行时异常(继承自 RuntimeException)触发回滚。这有助于保持数据的一致性,因为在发生异常时,事务将回滚到起始状态。

  5. 支持嵌套事务: @Transactional 注解支持嵌套事务,这意味着你可以在一个事务内调用另一个被 @Transactional 注解标记的方法,形成嵌套事务。嵌套事务允许更细粒度的事务控制。

总体而言,@Transactional 注解简化了事务管理的配置,提高了代码的可读性和灵活性,使得开发者能够更轻松地处理事务性操作,同时确保数据的一致性和完整性。

@Transactional 有什么缺点

尽管 @Transactional 注解提供了方便的事务管理机制,但也存在一些潜在的缺点和注意事项:

  1. 隐式事务传播: 在使用 @Transactional 注解时,有时难以准确了解事务的传播行为。一些复杂的调用链可能导致事务的传播方式与预期不符,因此开发者需要仔细了解注解属性的含义。

  2. 注解滥用: 过度使用 @Transactional 注解可能导致事务管理的不透明性,使得代码更难以理解和维护。因此,需要谨慎使用,只在确实需要事务管理的地方使用。

  3. 性能开销: 开启事务会带来一定的性能开销,尤其是在某些情况下,比如对大量数据的批量操作。在一些读操作为主的场景中,不合理的事务管理可能影响系统性能。

  4. 不同数据库支持不同: 不同的数据库对事务的支持程度有所不同,因此在使用 @Transactional 注解时,需要注意数据库的特性以及对事务的支持程度,以避免潜在的兼容性问题。

  5. 事务嵌套复杂性: 虽然支持嵌套事务是 @Transactional 注解的一项功能,但处理嵌套事务可能增加代码的复杂性,尤其是在出现回滚时需要仔细处理嵌套事务的状态。

  6. 不适用于所有场景: @Transactional 注解适用于大多数事务管理场景,但并不适用于所有情况。在某些特殊情况下,可能需要更细粒度的事务控制或者其他事务管理机制。

总体而言,虽然 @Transactional 注解为事务管理提供了方便和简化,但在使用时需要谨慎,根据具体业务需求和场景选择是否使用以及如何使用。对于复杂的事务场景,可能需要更深入的理解和配置。

@Transactional 哪些场景下会不生效

@Transactional 注解在大多数情况下是有效的,但也有一些场景下可能会导致注解不生效或产生意外的结果。以下是一些可能导致 @Transactional 不生效的场景:

  1. 非 Spring 管理的 Bean 方法调用: 如果 @Transactional 注解标记的方法是由同一个类内的另一个非 Spring 管理的 Bean 方法调用的,事务可能不会生效。这是因为 Spring 的事务管理是基于代理机制实现的,只有通过代理调用的方法才能被事务管理器感知。

  2. 自调用问题: 如果在同一个类内的方法内部自调用一个被 @Transactional 注解标记的方法,事务可能会失效。这是因为默认情况下 Spring 使用动态代理来实现事务,自调用内部方法不会触发代理。

  3. 运行时异常未被抛出: @Transactional 默认只对未捕获的运行时异常(继承自 RuntimeException)触发回滚。如果在被注解方法中捕获了异常并未重新抛出,事务可能不会回滚。

  4. 基于类的事务设置: 如果在类级别上使用了 @Transactional 注解,并且类中的方法没有符合事务属性的 @Transactional 注解,可能会导致事务不生效。

  5. 使用了其他事务管理机制: 如果应用中同时使用了多个事务管理机制,可能会导致冲突。例如,如果同时使用了 Spring 的声明式事务和编程式事务管理,可能会产生不一致的结果。

  6. 在非公共方法上使用: 在非公共(private、protected)的方法上使用 @Transactional 注解通常是无效的,因为 Spring 无法代理非公共方法。

  7. 异步方法: @Transactional 注解在异步方法上可能不会按预期生效。在异步方法上使用事务需要谨慎,可能需要额外的配置。

  8. 使用了 AspectJ 模式: 如果使用了 AspectJ 模式而不是 Spring 默认的动态代理模式,@Transactional 注解的行为可能会受到影响。

在使用 @Transactional 注解时,务必注意上述场景,并确保注解的生效符合预期。如果遇到问题,可以通过调整配置、调用代理对象或使用其他方式来解决。

@Transactional 最佳实践

以下是使用 @Transactional 注解时的一些最佳实践:

  1. 应用在公共方法上:@Transactional 注解应用在公共方法上,以确保 Spring 能够正确地创建代理对象并管理事务。
@Transactional
public void myPublicMethod() {// 事务性操作
}
  1. 慎重使用在私有方法: 避免在私有方法上使用 @Transactional 注解,因为 Spring 默认使用动态代理,私有方法无法被代理。如果需要在同一类内部调用事务性方法,可以通过将调用方法抽取到另一个类中,并确保被调用的方法是 public 的。

  2. 谨慎使用在构造函数中: 避免在构造函数中使用 @Transactional 注解,因为构造函数在对象创建时被调用,而此时事务可能尚未启动。将事务性操作移到其他方法中执行。

  3. 明确声明传播行为: 明确指定事务的传播行为,避免依赖默认值。根据业务需求选择适当的传播行为,如 Propagation.REQUIREDPropagation.REQUIRES_NEW 等。

@Transactional(propagation = Propagation.REQUIRED)
public void myMethod() {// 事务性操作
}
  1. 了解隔离级别: 了解不同的隔离级别,并根据具体业务需求选择合适的隔离级别。常见的隔离级别包括 Isolation.DEFAULTIsolation.READ_COMMITTED 等。
@Transactional(isolation = Isolation.READ_COMMITTED)
public void myMethod() {// 事务性操作
}
  1. 处理异常: 在事务性方法中,确保未捕获的运行时异常能够触发事务回滚。如果需要捕获异常,确保重新抛出未捕获的异常。
@Transactional
public void myMethod() {try {// 事务性操作} catch (Exception e) {// 处理异常throw e; // 重新抛出未捕获的异常,以触发事务回滚}
}
  1. 使用只读事务: 如果方法只涉及读操作而不涉及写操作,可以设置 readOnly 属性为 true,以提高性能。
@Transactional(readOnly = true)
public void myReadOnlyMethod() {// 读操作
}
  1. 合理设置超时时间: 如果方法可能执行较长时间,可以通过设置 timeout 属性来定义事务的超时时间,防止长时间持有数据库连接。
@Transactional(timeout = 300) // 事务超时时间为 300 秒
public void myMethod() {// 事务性操作
}
  1. 了解嵌套事务: 如果需要支持嵌套事务,了解嵌套事务的配置和行为,并确保业务逻辑与事务嵌套相符。
@Transactional(propagation = Propagation.REQUIRED)
public void myMethod() {// 事务性操作anotherTransactionalMethod(); // 嵌套事务
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void anotherTransactionalMethod() {// 另一个事务性操作
}
  1. 监控和日志: 在生产环境中,通过合适的监控工具和日志来跟踪事务的执行情况,以便及时发现和解决潜在的事务问题。

通过以上最佳实践,可以更好地使用 @Transactional 注解,并确保事务的正确性、一致性和性能。

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

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

相关文章

DAZ to maxon 实时面捕52个blendshapes 表情模板基本形中英文对照表

一、转自: DAZ to maxon 实时面捕52个blendshapes 表情模板基本形中英文对照表 - 哔哩哔哩 很多学员反映实时表情怎么就不同步呢?这个问题其实很常见。 第一:表情模板的顺序弄错,导致表情错乱。 第二:表情模板不标准…

leetcode—和为K的子数组

1 和为K的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums [1,1,1], k 2 输出:2示例 2: 输入&#xff1…

AbstractHttpMessageConverter + easyexcell优雅下载附件

介绍 AbstractHttpMessageConverter 是 Spring 框架中用于处理 HTTP 消息转换的抽象基类。它用于处理来自 HTTP 请求的消息,并将其转换为特定的 Java 对象,或者将 Java 对象转换为 HTTP 响应消息。 这个抽象类允许开发人员创建自定义的 HTTP 消息转换器,以便在 Spring MVC…

职务岗位的概念澄清及应用

背景 现在的企业数字化平台中,有一些术语组织管理中的术语,理解上很有歧义,并且命名和应用上简直五花八门,洋相百出,比如,我们的大厂,就把角色这次,可以作为分类、分组的标签就能大…

2024-01-15(SpringMVCMybatis)

1.拦截器:如果我们想在多个handler方法(controller中的方法)执行之前或者之后都进行一些处理,甚至某些情况下需要拦截掉,不让handler方法执行,那么就可以使用SpringMVC为我们提供的拦截器。 拦截器和过滤器的区别:过滤…

基于内容的图像web检索系统

题目:基于内容的图像在线检索系统 简介:基于内容的图像在线检索系统(Content Based Online Image Retrieval , 以下简称 CBOIR),是计算机视觉领域中关注大规模数字图像内容检索的研究分支。典型的CBOIR系统&#xff…

分布式事务Seata实战-AT模式(注册中心为Eureka)

大致记录Seata的AT模式下创建项目过程中需要注意的点和可能遇到的问题。 本项目是以官网的给的示例(即下图)进行创建的,以Eureka为注册中心。 官网:Seata AT 模式 | Apache Seata™ 官方代码示例: 快速启动 | Apac…

算法笔记(动态规划入门题)

1.找零钱 int coinChange(int* coins, int coinsSize, int amount) {int dp[amount 1];memset(dp,-1,sizeof(dp));dp[0] 0;for (int i 1; i < amount; i)for (int j 0; j < coinsSize; j)if (coins[j] < i && dp[i - coins[j]] ! -1)if (dp[i] -1 || dp[…

Doris配置外表以及多个Hive外表的配置

1.场景分析 以Clickhouse、Doris、Starrocks等为代表的mpp分析数据库正在快速的兴起&#xff0c;以其高效查询、跨库整合能力收到广大技术人员的喜爱。本文主要浅显介绍下作者在使用Doris时&#xff0c;通过建立catlog进行跨库查询。 废话不多少&#xff0c;直接上代码 2.相关…

力扣211. 添加与搜索单词 - 数据结构设计

字典树 思路&#xff1a; 设计一棵字典树&#xff0c;每个节点存放单词的一个字符&#xff0c;节点放一个标记位&#xff0c;如果是单词结束则标记&#xff1b;字典树插入&#xff1a; 字典树默认有 26 个 slot 槽代表 a - z&#xff1b;遍历单词&#xff0c;如果字符对应槽存…

哥德巴赫猜想不成立

哥德巴赫猜想是德国人哥德巴赫与瑞士人欧拉联手提出的素数与合数关系猜想&#xff1a;≥2的偶数素数素数。后来黎曼崛起&#xff0c;他把1剔除出素数队列&#xff0c;哥猜被整理为&#xff1a;≥6的偶数素数素数&#xff0c;≥9的奇数素数素数素数。 哥猜虽然是欧洲人的课题&am…

Python自动化实战之接口请求的实现

在前文说过&#xff0c;如果想要更好的做接口测试&#xff0c;我们要利用自己的代码基础与代码优势&#xff0c;所以该章节不会再介绍商业化的、通用的接口测试工具&#xff0c;重点介绍如何通过 python 编码来实现我们的接口测试以及通过 Pycharm 的实际应用编写一个简单接口测…

Redis应用(三)实现自动补全

自动补全往往给出部分提示供用户选择&#xff0c;这就涉及排序。有几下几种方法&#xff1a; 一、需要添加元素且数据量少 1、方案&#xff1a;数据量非常小时&#xff0c;程序从redis中获取数据后&#xff0c;在程序中排序。 &#xff08;1&#xff09;写数据&#xff1a;如…

『Open3D』1.10 Tensor数据处理

open3d中实现了自身的数据类型,用于open3d中内部算法的数值计算,但基础使用上与numpy类似。 目录 1、tensor创建 2、tensor数据属性 3、 Tensor数据在CPU与GPU上的转换

Linux/Traceback

Enumeration nmap 使用nmap初步扫描发现只开放了22和80端口&#xff0c;端口详细扫描情况如下 先看看web是什么样子的&#xff0c;打开网站发现有一条留言&#xff0c;显示该站点已经被黑了&#xff0c; 并且留下了后门 查看源代码&#xff0c;可以看到下面的注释 <!--So…

Docker中创建并配置MySQL、nginx、redis等容器

Docker中安装并配置MySQL、nginx、redis等 文章目录 Docker中安装并配置MySQL、nginx、redis等一、创建nginx容器①&#xff1a;拉取镜像②&#xff1a;运行nginx镜像③&#xff1a;从nginx容器中映射nginx配置文件到本地④&#xff1a;重启nginx并重新配置nginx的挂载 二、创建…

python编写的端口扫描脚本

实训项目制作的端口扫描脚本 附有详细的使用命令解释 可以实现单个端口进行扫描和端进行扫描 eg&#xff1a;1-65535 import optparse # 导入用于解析命令行参数的模块 import socket # 导入用于网络通信的模块 # 定义函数&#xff1a;扫描指定主机的指定端口 def PortSca…

Vue透传 Attributes的代码以及总结

//透传简单来说就是在子组件写style,class或者函数可以将它们&#xff0c;自动直接传递给 template&#xff1a;里面的单个节点。 //多个节点透传的自动传递会生效&#xff0c;如果在节点中像使用&#xff0c;那么就需要在对应的节点中写像:style"$attrs.style"的形…

LabVIEW精确测量产品中按键力和行程

项目背景 传统的按键测试方法涉及手工操作&#xff0c;导致不一致和效率低下。在汽车行业中&#xff0c;带有实体按键的控制面板非常常见&#xff0c;确保一致的按键质量至关重要。制造商经常在这些组件的大规模、准确测试中遇到困难。显然&#xff0c;需要一个更自动化、精确…

Kubernetes (十四) 调度策略

一. 调度策略 二. 调度方法 nodeName 创建pod配置文件 vim nodename.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels…