当前位置: 首页 > news >正文

【Spring事务】声明式事务 使用详解

在这里插入图片描述

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~

在这里插入图片描述

声明式事务

  • 一、编程式事务
  • 二、声明式事务
    • 🚀XML配置文件 设置
    • 🚀声明式事务的使用
  • 三、声明式事务的属性
    • ⚪只读
    • ⚪超时
    • ⚪回滚策略
    • ⚪隔离等级
    • ⚪传播行为
  • 四、全注解配置事务



一、编程式事务


事务的相关操作都需要我们自己去编写。

Connection conn = ...;try {// 开启事务:关闭事务的自动提交conn.setAutoCommit(false);// 核心操作// 提交事务conn.commit();}catch(Exception e){// 回滚事务conn.rollBack();}finally{// 释放数据库连接conn.close();}

主要缺陷

  • 细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,比较繁琐。
  • 代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,代码就没有得到复用。




二、声明式事务


框架将事务操作固定模式的代码抽取出来,进行相关的封装。

封装起来后,我们只需要在配置文件中进行简单的配置即可完成操作,可通过注解标注来使用事务。

  • 好处1:提高开发效率
  • 好处2:消除了冗余的代码
  • 好处3:框架会综合考虑相关领域中在实际开发环境下有可能遇到的各种问题,进行了健壮性、性能等各个方面的优化



🚀XML配置文件 设置


P命名空间

需要新增相关的p命名空间(可直接复制)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd">

相关设置

<!--配置事务管理器的bean
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="druidDataSource"></property>
</bean><!--开启事务的注解驱动通过注解@Transactional所标识的方法或标识的类中所有的方法,都会被事务管理器管理事务
-->
<!-- transaction-manager属性的默认值是transactionManager,如果事务管理器bean的id正好就是这个默认值,则可以省略这个属性 -->
<tx:annotation-driven transaction-manager="transactionManager" />



🚀声明式事务的使用


@Transactional 注解

我们通过 @Transactional 标签,来声明需要使用事务的位置,

@Transactional 标签 既可以声明类,也可以声明方法,

  • @Transactional 标识在方法上,则只会影响该方法

  • @Transactional 标识的类上,则会影响类中所有的方法

例如:

/*** @author .29.* @create 2023-02-28 21:21*/
@Transactional  //⭐事务声明⭐
@Service        //对象生成,存入IOC容器
public class BookServiceImpl implements BookService{@Autowired  //自动装备private BookDao bookDao;@Overridepublic void buyBook(Integer bookId, Integer userId) {//查询图书的价格Integer price = bookDao.getPriceByBookId(bookId);//更新图书的库存bookDao.updateStock(bookId);//更新用户的余额bookDao.updateBalance(userId, price);}
}




三、声明式事务的属性


⚪只读

使用

@Transactional(readOnly = true)

功能:

对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这样数据库就能够针对查询操作来进行优化

注意:
对增删改操作设置只读会抛出异常:
java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed



⚪超时

使用

@Transactional(timeout = 3)//数字3代表时间限制三秒

功能:

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。这大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。此时这个很可能出问题的程序应该被回滚,当事务执行超过我们设置的时间,就回滚事务,撤销它已做的操作,事务结束,释放资源。

结果:
超时回滚,抛出异常
org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was…



⚪回滚策略

使用

@Transactional(rollbackFor = .class)
@Transactional(noRollbackFor = .class)
@Transactional(rollbackForClassName = 全类名)
@Transactional(noRollbackForClassName= 全类名)

功能

声明式事务默认只针对运行时异常回滚,编译时异常不回滚。

可以通过@Transactional中相关属性设置回滚策略

 rollbackFor* :可让原本不回滚的回滚;noRollbascFor* :可让原本会回滚的不回滚
  • rollbackFor属性:需要设置一个Class类型的对象

  • rollbackForClassName属性:需要设置一个字符串类型的全类名

  • noRollbackFor属性:需要设置一个Class类型的对象

  • noRollbackForClassName属性:需要设置一个字符串类型的全类名



⚪隔离等级

使用

@Transactional(isolation = Isolation.DEFAULT)//使用数据库默认的隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)//读未提交
@Transactional(isolation = Isolation.READ_COMMITTED)//读已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)//可重复读
@Transactional(isolation = Isolation.SERIALIZABLE)//串行化

功能

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

  • 读未提交:READ_UNCOMMITTED
    允许Transaction01读取Transaction02未提交的修改。

  • 读已提交:READ_COMMITTED
    要求Transaction01只能读取Transaction02已提交的修改。

  • 可重复读:REPEATABLE_READ
    确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。

  • 串行化:SERIALIZABLE
    确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

在这里插入图片描述
在这里插入图片描述

 👆  隔离级别处理并发问题的能力,及数据库对其支持程度;👆


⚪传播行为

使用
通过@Transactional中的propagation属性设置事务传播行为

@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.SUPPORTS)
@Transactional(propagation = Propagation.MANDATORY)
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NEVER)
@Transactional(propagation = Propagation.NESTED)

功能
在service类中有a()方法和b()方法,a()方法上有事务,b()方法上也有事务,当a()方法执行过程中调用了b()方法,事务是如何传递的?合并到一个事务里?还是开启一个新的事务?这就是事务传播行为。

一共有七种传播行为:

  • REQUIRED:支持当前事务,如果不存在就新建一个(默认)

  • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行

  • MANDATORY:必须运行在一个事务中,如果当前没有事务正在发生,将抛出一个异常

  • REQUIRES_NEW:开启一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起

  • NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务

  • NEVER:以非事务方式运行,如果有事务存在,抛出异常

  • NESTED:如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于外层事务进行提交或回滚。如果外层事务不存在,行为就像REQUIRED一样。





四、全注解配置事务


案 例

配置类:

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;/*** @author .29.* @create 2023-03-01 8:36*/
@Configuration   //标记为Spring配置类
@ComponentScan("com.haojin.spring")  //设置扫描的包
public class SpringConfig {@Bean  //标记存放至IOC容器中的方法public DataSource getDataSource(){  //获取数据源对象的方法DruidDataSource druidDataSource = new DruidDataSource();//设置用于连接数据库的 用户 密码 url 驱动druidDataSource.setUrl("jdbc:mysql://localhost:3306/spring?characterEncoding=utf-8&useSSL=false");druidDataSource.setUsername("root");druidDataSource.setPassword("abc123");druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");return druidDataSource;}@Beanpublic JdbcTemplate getJdbcTemplate(DataSource dataSource){  //获取JdbcTemplate对象的方法JdbcTemplate jdbcTemplate = new JdbcTemplate();          //JdbcTemplate是spring封装的,实现jdbc相关操作类jdbcTemplate.setDataSource(dataSource);                  //设置数据源return jdbcTemplate;}@Beanpublic DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){ //获取事务管理器的方法DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); //获取DataSourceTransactionManager对象dataSourceTransactionManager.setDataSource(dataSource);               //为其设置数据源对象return dataSourceTransactionManager;}
}

测试:

import com.haojin.spring.controller.BookController;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** @author .29.* @create 2023-03-01 8:48*/
public class TxAllAnnotationTest {@Testpublic void test1(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);BookController bookController = context.getBean("bookController", BookController.class);bookController.buyBook(2,2);}
}



在这里插入图片描述

相关文章:

【Spring事务】声明式事务 使用详解

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 声明式事务一、编程式事务二、声明式事务&…...

学习28个案例总结

学习前 对于之前遇到的问题没有及时总结&#xff0c;导致做什么事情都是新的一样。没有把之前学习到接触到的内容应用上。通过这次对28个案例的学习。把之前遇到的问题总结成自己的经验&#xff0c;在以后的开发过程中避免踩重复性的坑。多看帮助少走弯路。 学习中 对28个案例…...

刷题Java常用方法总结

刷题Java常用方法总结 文章目录刷题Java常用方法总结快速查看:静态数组 Static Array初始化instance属性length技巧Arrays.sort从小到大排序Arrays.fill填满一个数组Arrays.copyOf / arr.clone()复制一个数组(二维数组也可以)动态数组 List & Dynamic Array初始化常规 - Ar…...

大数据技术之Hive

第1章Hive基本概念1.1 Hive1.1.1 Hive的产生背景在那一年的大数据开源社区&#xff0c;我们有了HDFS来存储海量数据、MapReduce来对海量数据进行分布式并行计算、Yarn来实现资源管理和作业调度。但是面对海量数据和负责的业务逻辑&#xff0c;开发人员要编写MR来对数据进行统计…...

第33篇:Java集合类框架总结

目录 1、集合概念 2、集合与数组的区别 3、集合框架的特性 1)高性能 2)可操作...

数据结构 | 栈的中缀表达式求值

目录 什么是栈&#xff1f; 栈的基本操作 入栈操作 出栈操作 取栈顶元素 中缀表达式求值 实现思路 具体代码 什么是栈&#xff1f; 栈是一种线性数据结构&#xff0c;具有“先进后出”&#xff08;Last In First Out, LIFO&#xff09;的特点。它可以看作是一种受限的…...

vue2前端实现html导出pdf功能

1. 功能实现方案 1.html转换成canvas后生成图片导出pdf&#xff08;本文选用&#xff09; html转canvas插件&#xff1a;html2canvas是一款将HTML代码转换成Canvas的插件&#xff1b;canvas生成pdf&#xff1a;jsPDF是一个使用Javascript语言生成PDF的开源库 2.HTML代码转出…...

用 ChatGPT 辅助学好机器学习

文章目录一、前言二、主要内容&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 探索更高效的学习方法可能是有志者共同的追求&#xff0c;用好 ChatGPT&#xff0c;先行于未来。 作为一个人工智能大语言模型&#xff0c;ChatGPT 可以在帮助初…...

【动态规划】最长上升子序列(单调队列、贪心优化)

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

海思SD3403/SS928V100开发(7)mcp2515-SPI转CAN驱动开发

1. 前言 需求: 需要一路can进行收发 分析: 根据目前使用较多的方案是使用主控端SPI接口 接入MCP2515芯片进行CAN协议转换 硬件: MCP2515->SPI2->SS928 2. Uboot开发 2.1 pinmux复用配置 2.1.1 修改uboot参数表 路径: osdrv/tools/pc/uboot_tools/ SS928V100…...

【安卓源码】SurfaceFlinger 启动及其与应用通信

1. surfaceFlinger 初始化和消息队列处理机制 surfaceflinger 的makefile 文件 /frameworks/native/services/surfaceflinger/Android.bp 235 cc_binary { 236 name: "surfaceflinger", 237 defaults: ["libsurfaceflinger_binary"], 238 i…...

springboot车辆充电桩

sprinboot车辆充电桩演示录像2022开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;ecli…...

linux进程和进程通信编程(1)

What makes the desert beautiful is that somewhere it hides a well. 沙漠之所以美丽,是因为在它的某个角落隐藏着一口井. linux进程和进程通信编程&#xff08;1&#xff09;1.什么是进程2.进程id(pid)3.进程间通信的方法管道信号IPCSocket4.创建进程forkfork有三个返回值父…...

操作系统(1.3)--习题

一、课堂习题 1、一个作业第一 次执行时用了5min ,而第二次执行时用了6min,这说明了操作系统的( )特点。 A、并发性 B、共享性 C、虚拟性 D、不确定性 D 2、在计算机系统中,操作系统是( )。 A、处于裸机之上的第一层软件 B、处于硬件之下的低层软件 C、处于应用软件之上的系统软…...

刷题笔记之十三(有假币、最难的问题、因子个数)

目录 1. 求正数数组的最小不可组成和 2. 有假币 3. 继承时先调用父类的构造方法;类中的成员变量的初始化操作都在构造方法时进行 4. 学会并理解装箱拆箱,注意new出来的也可以拆!! 5. getDeclaredMethods()是标识类或接口的声明成员(这个表示public private 包访问权限 pro…...

5个代码技巧,加速你的Python

5个代码技巧&#xff0c;加速你的Python 人生苦短&#xff0c;快学Python&#xff01; Python作为一种功能强大的编程语言&#xff0c;因其简单易学而受到很多初学者的青睐。它的应用领域又非常广泛&#xff1a;科学计算、游戏开发、爬虫、人工智能、自动化办公、Web应用开发…...

字节跳动软件测试岗,前两面过了,第三面HR天坑!竟然跟我说……

阎王易见&#xff0c;小鬼难缠。我一直相信这个世界上好人居多&#xff0c;但是也没想到自己也会在阴沟里翻船。我感觉自己被字节跳动的HR坑了。在这里&#xff0c;我只想告诫大家&#xff0c;offer一定要拿到自己的手里才是真的&#xff0c;口头offer都是不牢靠的&#xff0c;…...

[数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北

本文主要介绍GeoPandas的基本使用方法&#xff0c;以绘制简单的地图。GeoPandas是一个Python开源项目&#xff0c;旨在提供丰富而简单的地理空间数据处理接口。GeoPandas扩展了Pandas的数据类型&#xff0c;并使用matplotlib进行绘图。GeoPandas官方仓库地址为&#xff1a;GeoP…...

ChatGPT加强版GPT-4面世,打工人的方式将被颠覆

&#x1f517; 运行环境&#xff1a;chatGPT&#xff0c;GPT-4 &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#…...

Python逆向及相关知识

今天第二次看见python字节码的逆向题&#xff0c;然后发现了一个介绍Python逆向的文章&#xff0c;所以把文章里的内容简单整理记录一下。 文章参考&#xff1a;https://www.cnblogs.com/blili/p/11799398.html Python运行原理&#xff1a; 一.什么是Python Python 是一种解…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...