详细分析Java中的@Transactional注解

news2024/11/17 16:34:03

目录

  • 前言
  • 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. 非事务方法调用事务方法,要用代理对象调用否则事务会失效。而事务方法调用非事务不会失效。

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

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

相关文章

基于Hadoop的网上购物行为大数据分析及预测系统【flask+echarts+机器学习】前后端交互

有需要本项目或者部署的系统可以私信博主,提供远程部署和讲解 本研究基于淘宝用户行为的开源数据展开大数据分析研究,通过Hadoop大数据分析平台对阿里天池公开的开源数据集进行多维度的用户行为分析,为电商销售提供可行性决策。 首先我们将大…

完全卸载grafana

先停掉grafana sudo systemctl stop grafana-server 查看要卸载的包的名字 yum list installed yum remove grafana-enterprise.x86_64 成功 删除grafana的数据目录 sudo rm -rf /etc/grafana/sudo rm -rf /usr/share/grafana/sudo rm -rf /var/lib/grafana/

Webhook端口中的自定义签名身份认证

概述 如果需要通过 Webhook 端口从交易伙伴处接收数据,但该交易伙伴可能对于安全性有着较高的要求,而不仅仅是用于验证入站 Webhook 要求的基本身份验证用户名/密码,或者用户可能只想在入站 Webhook 消息上增加额外的安全层。 使用 Webhook…

canvas设置渐变色文字(线性、径向)

查看专栏目录 canvas示例教程100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

【机器学习300问】4、机器学习到底在学习什么?

首先我们先了解一个前置问题,再回答机器学习到底在学习什么。 一、求机器学习问题有哪几步? 求解机器学习问题的步骤可以分为“学习”和“推理”两个阶段。首先,在学习阶段进行模型的学习,然后,在推理阶段用学到的模型…

OpenHarmony——基于HDF驱动框架构建的Display驱动模型

概述 功能简介 LCD(Liquid Crystal Display)驱动编程,通过对显示器上电、初始化显示器驱动IC(Integrated Circuit)内部寄存器等操作,使其可以正常工作。 基于HDF(Hardware Driver Foundation…

使用nginx+HTML2canvas将任意html网页转为png图片自定义张数

文章目录 概述网页的转换html2canvas的使用导入导入HTML2canvas库函数定义 nginx部署编写控制截图网页代码iframe 网页控制代码 测试说明 概述 本文简述如何使用nginxhtml2canvas将任意网页html转为png图片 网页的转换 如果是本地网页,直接进行nginx反向代理就行…

数据库SELECT语句

文章目录 一、检索数据二、排序检索三、过滤数据四、数据过滤4.1 组合WHERE子句1. AND操作符2. OR操作符3. 计算次序 4.2 IN操作符4.3 NOT操作符 五、用通配符过滤LIKE操作符1. 百分号(%)通配符2. 下划线(_)通配符 使用通配符的技…

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

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

20240112-【UNITY 学习】实现第一人称移动教程

1、创建一个空物体,挂载Rigidbody组件,并设置相应参数 2、在上述空物体下创建一个胶囊体,两个空物体,一个用来控制朝向,另一个用来控制摄像机 3、给摄像机创建一个父物体,并挂载脚本MoveCamera_01.cs using…

【剪枝】【广度优先】【深度优先】488祖玛游戏

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 剪枝 广度优先 深度优先 488祖玛游戏 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 ‘R’、黄色 ‘Y’、蓝色 ‘B’、绿色 ‘G’ 或白色 ‘W’ 。你的手中也有一些…

flutter使用getx进行数据状态管理,实现页面响应式

无论是什么样的应用,都还是需要最基础的数据来支撑的,而且不同的页面之间可能需要共享数据状态,这就显得数据状态管理非常有必要了。因为我这里使用了get依赖库,所以就可以直接在项目中使用getx来管理状态,不想再使用别…

PDF-XChange Editor v10.2.0.384

软件介绍 PDF-XChange Editor,号称打开速度最快最强大的PDF编辑器/PDF阅读器,PDF-XChange专注于PDF文档的编辑,打开PDF文件速度快,软件小功能强大,可以自定义制作PDF电子文档,具有创建,查看&am…

2024年实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先,来看下效果图 在线体验地址:https://geojson.hxkj.vip,并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

基于Linux的Flappy bird游戏开发

项目介绍 主要是使用C语言实现,开启C项目之旅。 复习巩固C语言、培养做项目的思维。 功能: 按下空格键小鸟上升,不按下落; 显示小鸟需要穿过的管道; 小鸟自动向右飞行;(管道自动左移和创建&a…

1-Docker-基础

本文内容多处参考黑马程序员的公开资料,仅用来个人梳理,原资料地址:https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec Docker介绍 为什么要用Docker? 以Mysql安装为例,想要在Linux系统上安装Mysql&…

brpc: a little source code

之前在https://www.yuque.com/treblez/qksu6c/nqe8ip59cwegl6rk?singleDoc# 《olap/clickhouse-编译器优化与向量化》中我谈过brpc的汇编控制bthread。本文就来看一下brpc作为一个高性能的rpc实现,除了自定义线程栈之外,代码还有什么优秀之处。 因为时间…

Windows11 安装MySQL8.0操作

一、从MySQL官网下载MySQL安装包 官网地址: www.mysql.com (1)首先 选择 DOWNLOADS 下载界面 (2)其次选择 MySQL 客户端 下载 (3)选择windows安装MySQL (4)选择MySQL类型…

【目标检测】YOLOv5算法实现(八):模型验证

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github,删减了源码中部分内容,满足个人科研需求。   本系列文章主要以YOLOv5为例完成算法的实现,后续修改、增加相关模…

【DevOps-08-3】Jenkins容器内部使用Docker

一、简要描述 构建镜像和发布镜像到harbor都需要使用到docker命令。而在Jenkins容器内部安装Docker官方推荐直接采用宿主机带的Docker即可。 设置Jenkins容器使用宿主机Docker。 二、配置和操作步骤 1、修改宿主机docker.sock权限 # 修改docker.sock 用户和用户组都为root $ …