详细分析Java中的@Transactional注解
创始人
2024-11-04 06:11:41
0

目录

  • 前言
  • 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 {      @Autowired     private UserService userService;      @Transactional     public 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 {      @Autowired     private JdbcTemplate jdbcTemplate;      @Transactional     public void decreaseBalance(String account, double amount) {         // 扣除余额的数据库更新操作         // ...     }      @Transactional     public 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. 非事务方法调用事务方法,要用代理对象调用否则事务会失效。而事务方法调用非事务不会失效。

相关内容

热门资讯

技巧辅助挂!pokermast... 技巧辅助挂!pokermaster修改器,丹东约战麻将辅助器,演示教程(有挂细节)1、点击下载安装,...
现场直击!wepokerplu... 现场直击!wepokerplus万能挂,丰城双剑新版最强高分攻略,操作教程(有挂方针)1.丰城双剑新...
插件辅助挂!wepoker有辅... 插件辅助挂!wepoker有辅助器吗,乐平包王攻略,学习教程(有挂方略)1、首先打开乐平包王攻略辅助...
据玩家消息!拱趴大菠萝辅助神器... 据玩家消息!拱趴大菠萝辅助神器,多乐跑得快辅助器,机巧教程(证实有挂)1、在拱趴大菠萝辅助神器插件功...
此事备受玩家关注!来玩app破... 此事备受玩家关注!来玩app破解版,h5能反杀吗,绝活教程(有挂详细)1、打开软件启动之后找到中间准...
值得注意的是!aapoker破... 值得注意的是!aapoker破解侠是真的吗,蜀山四川游戏修改工具,经验教程(有挂助手)1、金币登录送...
第三方辅助!wepoker脚本... 第三方辅助!wepoker脚本,广东星悦有外开挂辅助器吗,法门教程(有挂分析)广东星悦有外开挂辅助器...
此事引发广泛关注!德州透视脚本... 此事引发广泛关注!德州透视脚本,崇阳斗棋辅助脚本视频,诀窍教程(的确有挂)暗藏猫腻,小编详细说明崇阳...
黑科技辅助挂!wepoker买... 黑科技辅助挂!wepoker买脚本靠谱吗,情怀七喜游戏辅助,法门教程(有挂方法)1、每一步都需要思考...
方法辅助挂!aapoker怎么... 方法辅助挂!aapoker怎么设置提高好牌几率,蘑菇云辅助使用视频,绝活儿教程(讲解有挂)1、完成蘑...