SpringBoot - @Transactional注解详解

news2024/10/6 2:30:46

简介

Spring中的@Transactional注解,基于动态代理的机制,提供了一种透明的事务管理机制,方便快捷的解决在开发中碰到的问题,@Transactional 的事务开启 ,或者是基于接口的或者是基于类的代理被创建。Spring为了更好的支撑数据库操作,在框架中支持了两种事务管理的方式:编程式事务和声明式事务,能够保证作单个逻辑工作单元执行的一系列操作,要么同时成功,要么同时失败。

如何使用

(1)可以作用在类和方法上。
(2)建议不要作用在接口或接口的方法上,因为只有使用基于接口的代理时注解才有效。建议作用在实现类的方法上。
(3)当作用在类上时,该类的PUBLIC方法都具有该类型是事务属性,但是使用作用在方法上的注解来覆盖类级别的定义。
(4)方法的访问权限为PUBLIC。
(5)@Transactional(rollbackFor=Exception.class),如果方法上加了这个注解,那么当这个方法抛出异常时(运行时和非运行时)就会回滚,数据库里面的数据也会回滚。如果不配置rollbackFor属性,那么事物只会在遇到运行时异常才会回滚。
(6)默认情况下,SPRING只有在抛出的异常为运行时且为unchecked 异常才会回滚事务,也就是抛出的异常为RuntimeException 的子类(Errors也会)时才会回滚事务,而抛出 checked 异常则不会回滚事务 ,当然可以通过 @Transactional rollbackFor进行配置。

(6.1)checked异常: 一般是指程序不能直接控制的外界情况,是指在编译的时候就需要检查的一类异常,用户程序中必须采用try-catch机制处理或者通过throws交由调用者来处理。这类异常主要是指除了Error以及RuntimeException及其子类之外的异常。
(6.2)unchecked异常:一般是那些不在编译的时就要处理的一类异常。在JAVA体系里,所有的Error以及RuntimeException及其子类都是unchecked异常。
在这里插入图片描述

1. 源码定义
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	// 可选的限定描述符,指定使用的事务管理器
	@AliasFor("transactionManager")
	String value() default "";

	@AliasFor("value")
	String transactionManager() default "";

	String[] label() default {};

	// 可选的事务传播机制
	Propagation propagation() default Propagation.REQUIRED;

	// 可选的事务隔离级别
	Isolation isolation() default Isolation.DEFAULT;

	// 事务超时时间设置
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	String timeoutString() default "";

	boolean readOnly() default false;

	// 导致事务回滚的异常类
	Class<? extends Throwable>[] rollbackFor() default {};

    // 导致事务回滚的异常类名称
	String[] rollbackForClassName() default {};
	
	// 不会导致事务回滚的异常类
	Class<? extends Throwable>[] noRollbackFor() default {};

    // 不会导致事务回滚的异常类名称
	String[] noRollbackForClassName() default {};

}
2. 传播机制
序号机制名称描述
1REQUIRED默认值,如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。
2REQUIRES_NEW首先创建一个新的事务,如果当前存在事务,则把当前事务挂起。
3SUPPORTS如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
4NOT_SUPPORTED以非事务方式运行,如果当前存在事务,则把当前事务挂起。
5NEVER以非事务方式运行,如果当前存在事务,则抛出异常。
6MANDATORY如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
7NESTED如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行; 如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
3. 隔离级别
序号名称描述
1DEFAULT使用后端数据库默认的隔离级别
2READ_UNCOMMITTED读取未提交数据(会出现脏读, 不可重复读)
3READ_COMMITTED读取已提交数据(会出现不可重复读和幻读)
4REPEATABLE_READ可重复读(会出现幻读)
5SERIALIZABLE串行化

使用场景

1. 同一个类

场景1

同一类中有A和B两个方法,A方法上没有@Transactional注解,B方法上有,上层应用通过A方法间接调用B方法,B方法抛出异常,此时A方法和B方法操作都不会回滚。


public void a() {
	b();
}
@Transactional(rollbackFor = Exception.class)
public void b() {
}
场景2

同一类中有A和B两个方法,A方法上有@Transactional注解,B方法上没有,上层应用通过A方法间接调用B方法,B方法抛出异常,此时A方法和B方法操作全部回滚。

@Transactional(rollbackFor = Exception.class)
public void a() {
	b();
}
public void b() {
}
场景3

同一类中有A和B两个方法,A方法和B方法上都有@Transactional注解,上层应用通过A方法间接调用B方法,B方法抛出异常,此时A方法和B方法操作全部回滚。

@Transactional(rollbackFor = Exception.class)
public void a() {
	b();
}
@Transactional(rollbackFor = Exception.class)
public void b() {
}

2. 不同的类

场景1

类1中有A方法,类2中有B方法,A方法上有@Transactional注解,B方法上没有,上层应用通过A方法间接调用B方法,B方法抛出异常,此时A方法和B方法操作全部回滚。

@Transactional(rollbackFor = Exception.class)
public void a() {
	b();
}
public void b() {
}
场景2

类1中有A方法,类2中有B方法,A方法和B方法上都有@Transactional注解,上层应用通过A方法间接调用B方法,B方法抛出异常,此时A方法和B方法操作全部回滚。

@Transactional(rollbackFor = Exception.class)
public void a() {
	b();
}
@Transactional(rollbackFor = Exception.class)
public void b() {
}
场景3

类1中有A方法,类2中有B方法,A方法和B方法上都有@Transactional注解,上层应用通过A方法间接调用B方法,B方法抛出异常,但是A方法捕获了异常,此时B方法操作回滚,A方法抛出异常。

@Transactional(rollbackFor = Exception.class)
public void a() {
	try {
	    b();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@Transactional(rollbackFor = Exception.class)
public void b() {
}
场景4

类1中有A方法,类2中有B方法,A方法和B方法上都有@Transactional注解,上层应用通过A方法间接调用B方法,B方法抛出异常,但是A方法捕获了异常,此时B方法操作回滚,A方法操作成功。

@Transactional(rollbackFor = Exception.class)
public void a() {
	try {
	    b();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void b() {
}

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

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

相关文章

数据库SQL查询(二)之连接查询

本文介绍SQL查询&#xff0c;如何在海量数据中筛选想要数据&#xff1b; 数据库管理系统选择&#xff1a;关系型数据库mysql 数据库管理工具选择&#xff1a;navicat 本文中查询语句和查询案例参考自&#xff1a;https://edu.csdn.net/course/detail/27673?ops_request_mis…

python django vue httprunner 实现接口自动化平台(最终版)

一、项目介绍&#xff1a; 1.1 项目地址 前端地址&#xff1a; GitHub - 18713341733/test_platform_service: django vue 实现接口自动化平台 后端地址&#xff1a; GitHub - 18713341733/test_platform_front: Django vue实现接口自动化平台 1.2 项目介绍 1.2.1 环境…

在 K8S 中部署一个应用 上

本身在 K8S 中部署一个应用是需要写 yaml 文件的&#xff0c;我们这次简单部署&#xff0c;通过拉取网络上的镜像来部署应用&#xff0c;会用图解的方式来分享一下&#xff0c;过程中都发生了什么 简单部署一个程序 我们可以通过 kubectl run 的方式来简单部署一个应用&#…

Python深度学习027:什么是梯度、梯度消失、梯度爆炸以及如何解决

文章目录 1. 梯度的概念2. 梯度更新中存在的问题2.1 梯度消失2.2 梯度爆炸3. 解决办法3.1 梯度消失3.2 梯度爆炸1. 梯度的概念 在机器学习中,梯度是指一个多元函数在某一点处的变化率以及变化的方向。 对于一个参数化的函数,梯度可以告诉我们在一个特定的点处函数值增加最快…

分布式系统概念和设计——Mach实例研究

分布式系统概念和设计 Mach实例研究 Mach主要抽象概述 任务 一个Mach任务是一个执行环境主要包括一个被保护的地址空间和一个内存管理的权能集合这些权能主要用于访问端口 线程 任务可以包含多个线程在共享内存的多处理器中&#xff0c;属于同一个任务的线程可以在不同的处理…

【案例实战】SpringBoot整合Redis实现缓存分页数据查询

正式观看本文之前&#xff0c;设想一个问题&#xff0c;高并发情况下&#xff0c;首页列表数据怎么做&#xff1f; 类似淘宝首页&#xff0c;这些商品是从数据库中查出来的吗&#xff1f;答案肯定不是&#xff0c;在高并发的情况下&#xff0c;数据库是扛不住的&#xff0c;那么…

Java解析XML文件(DOM4J解析xml文件)

内容重点1&#xff1a;DOM4J创建、解析、修改XML文件 内容重点2&#xff1a;DOM4J模拟解析web.xml配置文件&#xff0c;实现实例化servlet 1、什么是xml Xml(Extensible Markup Language) 一种扩展性标示语言,出现的意义其实与JSON字符串的意义相似,是新一代的数据交换标准…

怎么加密共享文件夹?局域网共享文件夹加密方法

相信很多企业都在使用局域网共享文件夹&#xff0c;它可以很方便地实现各部门之间的沟通协作。但是由于使用人员众多&#xff0c;数据安全非常难以得到保障。那么我们该怎么加密局域网共享文件夹呢&#xff1f; 共享文件夹加密 首先&#xff0c;我们先来了解一下共享文件夹加密…

某农业大学数据结构A-第13周作业

1.拓扑排序 【问题描述】 拓扑排序的流程如下&#xff1a; 1. 在有向图中选一个没有前驱的顶点并且输出之&#xff1b; 2. 从图中删除该顶点和所有以它为尾的弧。 重复上述两步&#xff0c;直至全部顶点均已输出&#xff0c;或者当前图中不存在无前驱的顶点为止。后一种情况则…

渲染模式差异和选择

传统服务端渲染 在过去传统开发中&#xff0c;页面渲染任务是由服务端完成的&#xff0c;服务器负责获取数据&#xff0c;拼装页面&#xff0c;客户端仅负责内容显示&#xff0c;使用这种方式的典型技术有 JSP、PHP、ASP.NET 等等。 客户端渲染 CSR Vue.js、React 这类框架之…

专访蘑菇物联沈国辉:做工业AI时代的推动者

在中国制造迈向高质量发展的进程中&#xff0c;数智化转型会成为破局之道。在这其中&#xff0c;蘑菇物联除了是一个本分的答题者&#xff0c;还是一个善于发现问题的贡献者。 作者|思杭 编辑|皮爷 出品|产业家 从广州造纸厂到广州造船厂&#xff0c;从第一橡胶厂到电池厂&a…

利用R语言通过百度地图API进行批量地理编码

利用R语言通过百度地图API进行批量地理编码 当您有大量的地点名称需要在地图上来呈现时&#xff0c;首先要在在线地图上找到该地址的坐标&#xff0c;通常是指经纬度&#xff0c;如果能够用代码来实现&#xff0c;便少了许多费时费力的体力活儿&#xff0c;以下将详细介绍地理…

数据结构的一些总结---利用Python实现

大家好&#xff0c;我是北山啦&#xff0c;本文简单介绍Python数据结构的相关内容&#xff0c;简单就是很简单的那种 文章目录 查找线性查找 O(n)二分查找(Binary Search) O(logn) 排序排序Low B三人组冒泡排序选择排序插入排序 排序NB三人组快速排序归并排序 数据结构栈和队列…

[Day 3 of 17]Building a document scanner in OpenCV

a computer vision-powered document scanner 计算机视觉驱动的文档扫描仪&#xff0c;三个步骤&#xff1a; 边缘检测edges通过边缘&#xff0c;找到代表待扫描纸张的轮廓contour应用透视转换(a perspective transform)获得文档自上而下的视图 How to Build a Kick-Ass Mob…

录音转文字的方法有哪些?这三个录音转文字的方法有哪些

你是否曾经遇到过这样的场景&#xff1a;在开会或者采访时&#xff0c;需要记录重要信息&#xff0c;但是手写记录或打字速度跟不上对话节奏&#xff0c;甚至难以记录所有细节。此时&#xff0c;录音转文字软件就派上用场了。然而&#xff0c;市场上有太多种选择&#xff0c;到…

【Vue3 生态】Vue Router 路由知识概览

前言 在 Web 前端开发中&#xff0c;路由是非常重要的一环&#xff0c;但是路由到底是什么呢&#xff1f; 从路由的用途上讲 路由是指随着浏览器地址栏的变化&#xff0c;展示给用户不同的页面。 从路由的实现原理上讲 路由是URL到函数的映射。它将 URL 和应用程序的不同部分…

低代码平台——提高研发效率的神器

一、前言 听起来像是一个噱头&#xff0c;但是低代码确实是一个能够快速提高研发效率的神器。 通过使用低代码平台&#xff0c;研发人员可以节省好几个月的时间&#xff0c;将前后端各种功能可视化以搭积木的形式快速完成。今天&#xff0c;我们将深入探讨低代码开发平台的特点…

两阶段目标检测指南:R-CNN、FPN、Mask R-CNN

动动发财的小手&#xff0c;点个赞吧&#xff01; Source[1] 多阶段&#xff08;Two-stage&#xff09;物体检测 计算机视觉中最基本和最广泛研究的挑战之一是目标检测。该任务旨在在给定图像中绘制多个对象边界框&#xff0c;这在包括自动驾驶在内的许多领域非常重要。通常&am…

一种看门狗复位电源的电路

如下是一个看门狗复位电源的电路&#xff1a; 满足掉电能被监测到&#xff0c;掉电后利用法拉电容保持后级模组继续工作一段时间。 看门狗可以关闭电源 320ms 20ms &#xff0c;对后级模组起到断电复位作用。 同时复位电源拉低的是VCC_4V 而非超级电容所在的VCC_4V_IN,并不会…

SpringBoot项目的事务实现

说明&#xff1a;当业务中的某个功能&#xff0c;需要多个操作组合执行才能完成时&#xff08;如删除部门&#xff0c;部门下的员工也需要同步删除时&#xff09;&#xff0c;为了保证数据的一致性&#xff0c;需要对这些组合操作添加事务。&#xff08;参考&#xff1a;http:/…