Spring事务的实现方式和实现原理;事务声明的方式,Spring的事务传播行为,spring事务的实现原理

Spring事务的实现方式和实现原理

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

什么是事务
数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么一起成功,要么一起失败,是一个不可分割的工作单元。

在我们日常工作中,涉及到事务的场景非常多,一个 service 中往往需要调用不同的 dao 层方法,这些方法要么同时成功要么同时失败,我们需要在 service 层确保这一点

事务的四大特性:A:原子性 C:一致性 I:隔离性 D:持久性

Spring支持的事务管理类型, spring 事务实现方式有哪些?

Spring支持两种类型的事务管理:

编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

Spring中事务的实现方式

1、编程式—实现事务

​ 在applicationContext.xml中配置好数据源,和事务管理器:

在这里插入图片描述

以上这种方式 不推荐使用,代码入侵太多。大量的处理事务的代码穿插到业务代码中

在这里插入图片描述

2、声明式—实现事务

(1)、声明式事务:xml形式 提前配置好数据源

  • 配置事务管理器
  • 配置通知,添加事务的切面
  • Aop的织入,将切面和切入点绑定起来

在这里插入图片描述

(2)、configration配置类的形式配置声明式事务

​ 1、配置好数据源信息 2、配置事务管理器 3、开启事务的注解支持

在这里插入图片描述

将该配置类添加到包扫描路径下,接来下就可以直接在service的方法或者类上使用@Transactional注解给方法添加事务

(3)、xml+注解方式配置声明式事务

在这里插入图片描述

配置完成后,只需要在想要开启注解的方法上加上@Transactional注解就可以了

说一下Spring的事务传播行为

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。

① PROPAGATION_REQUIRED:默认的事务传播,如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

在一个事务执行的过程中,调用另一个事务时候(比如一个service方法调用另一个service方法),这个事务将以何种状态存在,是两个事务共存呢,还是一个事务是另一个事务的子事务,还是一个事务加入另一个事务的子事务呢……利用事务的传播性来解决这个问题。

​ 1、REQUIRED: spring默认的事务的传播性
REQUIRED 表示如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

@Service
public class AccountService {@AutowiredJdbcTemplate jdbcTemplate;@Transactionalpublic void handle1() {jdbcTemplate.update("update user set money = ? where id=?;", 1, 2);}
}
@Service
public class AccountService2 {@AutowiredJdbcTemplate jdbcTemplate;@AutowiredAccountService accountService;public void handle2() {jdbcTemplate.update("update user set money = ? where username=?;", 1, "zhangsan");accountService.handle1();}
}

如果 handle2 方法本身是有事务的,则 handle1 方法就会加入到 handle2 方法所在的事务中,这样两个方法将处于同一个事务中,一起成功或者一起失败(不管是 handle2 还是 handle1 谁抛异常,都会导致整体回滚)。

如果 handle2 方法本身是没有事务的,则 handle1 方法就会自己开启一个新的事务。

2、REQUIRES_NEW
​ REQUIRES_NEW 表示创建一个新的事务,如果当前存在事务,则把当前事务挂起。换言之,不管外部方法是否有事务,REQUIRES_NEW 都会开启自己的事务。

3、NESTED
​ NESTED 表示如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 TransactionDefinition.PROPAGATION_REQUIRED。

4、MANDATORY
​ MANDATORY 表示如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

5、SUPPORTS
​ NOT_SUPPORTED 表示以非事务方式运行,如果当前存在事务,则把当前事务挂起。

6、NOT_SUPPORTED
​ NOT_SUPPORTED 表示以非事务方式运行,如果当前存在事务,则把当前事务挂起。

7、NEVER
​ NEVER 表示以非事务方式运行,如果当前存在事务,则抛出异常。

spring事务的实现原理

​ 底层是通过aop进行实现,@Transactional注解使用环绕通知,在进入方法前开启事务 。使用try catch包含目标方法,执行目标方法,执行完成后如果没有抛出异常,就提交事务。如果抛出异常就进行回滚

代码实现:

定义注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface rkTransactional {
}

切面:

@Aspect
@Component
@Slf4j
public class ExtrkThreadAop {@Autowiredprivate RkTransaction rkTransaction;/*** 只要方法上有加上rkTransactional 走around()* 异常通知* @param joinPoint* @throws Throwable*/@Around(value = "@annotation(com.rk.aop.rkTransactional)")public Object around(ProceedingJoinPoint joinPoint) {// 在目标方法之前开启事务  底层实现:将事务状态保存在当前线程里面TransactionStatus transactionStatus = rkTransaction.begin();try {Object result = joinPoint.proceed();//目标方法log.info("目标方法之后执行");//提交事务rkTransaction.commit(transactionStatus);return result;} catch (Throwable throwable) {// 目标方法执行向外抛出异常之后 手动回滚rkTransaction.rollback(transactionStatus);return "fail";}}
}

注解类:

@Component
public class RkTransaction {@Autowiredprivate DataSourceTransactionManager dataSourceTransactionManager;// 开启事务public TransactionStatus begin() {TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());return transaction;}// 提交事务public void commit(TransactionStatus transactionStatus) {dataSourceTransactionManager.commit(transactionStatus);}// 回滚事务public void rollback(TransactionStatus transactionStatus) {dataSourceTransactionManager.rollback(transactionStatus);}
}

test: 测试

    /*** 使用事务注解 事务到底在什么时候提交呢?该方法没有抛出异常的情况下就会自动提交事务* aop* @param name* @return*/@GetMapping("/insertUser")@rkTransactionalpublic String insertUser(String name) {int result = userMapper.insertUser(name);if ("rk".equals(name)) {int j = 1 / 0;}return result > 0 ? "ok" : "fail";}
}

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

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

相关文章

Co-DETR:DETRs与协同混分配训练论文学习笔记

论文地址:https://arxiv.org/pdf/2211.12860.pdf 代码地址: GitHub - Sense-X/Co-DETR: [ICCV 2023] DETRs with Collaborative Hybrid Assignments Training 摘要 作者提出了一种新的协同混合任务训练方案,即Co-DETR,以从多种标…

gmapping仿真

文章目录 获取源码安装依赖项编译简单场景运行gmapping开启键盘控制通过launch文件来启动gmappingGmapping建图的参数设置地图的保存和加载参考 获取源码 cd ~/catkin_ws/src/ git clone https://gitcode.com/weixin_42990464/wpr_simulation.git git clone https://gitcode.c…

【开源】基于Vue.js的农村物流配送系统的设计和实现

项目编号: S 024 ,文末获取源码。 \color{red}{项目编号:S024,文末获取源码。} 项目编号:S024,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2…

小程序:用户查找英语单词的意思 ← Python字典

【程序分析】 ● 字典中的条目是没有顺序的。 ● 可以对字典使用如下方法: keys()、values()、 items()、 clear()、 get(key)、 pop(key) 和popitem()【程序代码】 dictionary{"dog":"狗","apple":"苹果","banana&q…

Java字节码指令集概述及分类详解

Java全能学习面试指南:https://javaxiaobear.cn 1、字节码指令集与解析概述 Java字节码对于虚拟机,就好像汇编语言对于计算机,属于基本执行指令。 Java 虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码&a…

医院供暖换热站远程监控案例

医院供暖换热站远程监控案例 本文针对医院换热站远程监控系统存在的问题,提出了一种基于物联网技术的解决方案。通过使用云平台功能,实现对换热站设备的远程监控和管理,提高系统运行效率,降低运维成本。 一.痛点 1、…

C语言——深入理解指针(1)

目录 1.内存与地址 1.1 什么是内存 1.2 编址 2. 指针的变量和地址 2.1 取地址(&) 2.2 指针变量 2.3 解引用 2.4 指针变量大小 3. 指针变量类型存在的意义 3.1 不同类型指针的解引用 3.2 指针对整数的运算(,-&#…

(10)ATF MMU转换表

MMU简介 MMU(内存管理单元)负责将软件使用的虚拟地址转换为内存系统中使用的物理地址。MMU包括两个模块:TLB(Translation Lookaside Buffer)和TWU(Table Walk Unit)。TLB缓存最近使用的转换&am…

Spring Beans;Spring Bean的生命周期;spring Bean的作用域,spring处理线程并发问题

文章目录 Spring Beans请解释Spring Bean的生命周期解释Spring支持的几种bean的作用域Spring容器中的bean可以分为5个范围: Spring如何处理线程并发问题? 在现在的项目开发中经常使用到spring bean,那么来谈谈spring bean的生命周期&#xff…

APP软件线上排查方法

在线上环境中排查APP软件的问题是一项关键任务,需要使用一系列方法和工具来识别、定位和解决问题。以下是一些建议的排查方法,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.监控和日志…

linux如何查看文件的hash数值

在Linux系统中,你可以使用各种工具来查看文件的哈希值。下面是一些常见的方法: md5sum命令: md5sum 文件名例如: md5sum example.txtsha1sum命令: sha1sum 文件名例如: sha1sum example.txtsha256sum命令&a…

代码规范有用吗?听听100W年薪谷歌大佬怎么说!

谷歌内部的 python 代码规范 熟悉 python 一般都会努力遵循 pep8 规范,也会有一些公司制定内部的代码规范。大公司制定规范的目的不是说你一定要怎样去使用编程语言,而是让大家遵守同一套规则,节省其他人阅读代码的成本,方便协作…

红酒按照糖含量怎么分类?

我们常听人们形容葡萄酒为干型或甜型,这指的是葡萄酒的含糖量。不含糖就是干型,含糖少就是半干型,含糖多就是甜型,这是葡萄酒分类的一种——按糖量分。云仓酒庄的品牌雷盛红酒分享一般分为干型、半干型、半甜型、甜型四种。 云仓…

Jetson orin(Ubuntu20.04)不接显示器无法输出VNC图像解决办法以及vnc安装记录

sudo apt install vino 好像Jetpack 5.0中已经自带了。。 配置VNC server: gsettings set org.gnome.Vino prompt-enabled false gsettings set org.gnome.Vino require-encryption false 编辑org.gnome,增加一个“enabled key”的参数: cd /usr/share/glib-2…

氮化镓的晶体学湿式化学蚀刻法

引言 目前,大多数III族氮化物的加工都是通过干法等离子体蚀刻完成的。干法蚀刻有几个缺点,包括产生离子诱导损伤和难以获得激光器所需的光滑蚀刻侧壁。干法蚀刻产生的侧壁典型均方根(rms)粗糙度约为50纳米,虽然已经发现KOH基溶液可以蚀刻AlN…

服务台需要跟踪的3个重要指标MTBF+MTTF+MTTR

衡量标准是IT服务管理的核心,可提供有关运营的见解,并帮助确定需要持续改进的领域。通常的服务台指标有助于展示内部运营效率。例如,衡量在规定时间内解决问题的工单数量的 SLA 是展示服务台效率的关键因素。另一方面,故障指标可帮…

ate测试原理及ate测试系统(软件)知识科普 -纳米软件

ATE(Automatic Test Equipment)测试也叫自动化测试,通过计算机控制测试仪器对被测对象进行测试。以计算机编程代替人工测试,基于测试程序控制仪器并对待测品进行输入和输出信号检测分析,从而判断待测品的性能是否符合要求。 ATE测试需要根据测…

linux进程调度(一)-进程概述

一、什么是进程 进程是指计算机已运行的程序。程序本身只是指令、数据及其组织形式的描述。进程就是一个程序的执行实例,也就是正在执行的程序。在linux操作系统的中,进程就是一个担当分配系统资源CPU时间、内存的实体。进程控制的主要功能是对系统中的所…

2023年微软开源八个人工智能项目

自2001年软件巨头微软前首席执行官史蒂夫鲍尔默对开源(尤其是Linux)发表尖刻言论以来,微软正在开源方面取得了长足的进步。继ChatGPT于去年年底发布了后,微软的整个2023年,大多数技术都是面向开发人员和研究人员公开发…

HarmonyOS 设备管理开发:USB 服务开发指导

基本概念 USB 服务是应用访问底层的一种设备抽象概念。开发者根据提供的 USB API,可以获取设备列表、控制设备访问权限、以及与连接的设备进行数据传输、控制命令传输等。 运作机制 USB 服务系统包含 USB API、USB Service、USB HAL。 图 1 USB 服务运作机制 ●…