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

news2024/11/16 19:33:20

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 {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Transactional
    public void handle1() {
        jdbcTemplate.update("update user set money = ? where id=?;", 1, 2);
    }
}
@Service
public class AccountService2 {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    AccountService 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 {
    @Autowired
    private 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 {
 
    @Autowired
    private 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")
    @rkTransactional
    public String insertUser(String name) {
        int result = userMapper.insertUser(name);
        if ("rk".equals(name)) {
            int j = 1 / 0;
        }
        return result > 0 ? "ok" : "fail";
    }
}

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

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

相关文章

Tomcat注册为服务后,如何配置Tomcat内存大小

前提条件:tomcat已经注册为服务。 1.winR,输入regedit打开注册表 2.找到Tomcat注册表路径: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat80603.找到jvm内存配置路径: HKEY_LOCAL_MACHINE\SOFTW…

骨传导耳机的优缺点都有哪些?骨传导耳机值得入手吗?

骨传导耳机的优点还是很多的,相比于传统耳机,骨传导耳机要更值得入手! 下面让我们了解下骨传导耳机的优缺点都有哪些: 一、优点 1、使用更安全 传统的耳机,在使用时会听不到外界的声音,而骨传导耳机通过…

【SpringCloud】微服务架构设计模式

一、聚合气微服务设计模式 最常见、最简单的设计模式,效果如图所示: 聚合器调用多个服务实现应用程序所需的功能 它可以是一个简单的 Web 页面,将检索到的数据进行处理并展示,也可以是一个更高层次的组合微服务,对…

快手ConnectionError

因为运行的程序被中断导致 top然后查看站用处内存高的accelerate kill进程号 9回车

NFC技术简介

NFC简介 NFC(近场通信,Near Field Communication)是一种短距高频的无线电技术,由非接触式射频识别(RFID)演变而来。 NFC工作频率为13.56Hz,通常只有在距离不超过4厘米时才能启动连接,其传输速度有106 Kbit/秒、212 Kb…

IBM V5000存储报错控制器脱机节点自动恢复失败

PS:友情分享,请注意报错信息是否与本文一致。设备有价,数据无价,谨慎操作! 报错信息: 存储为双控制器互相冗余,目前node2脱机,node1已承载所有业务 处理方案: 登录进n…

SpringBoot+SSM项目实战 苍穹外卖(1)

目录 产品原型与技术选型后端环境搭建Git版本控制IDEA中运行sql脚本文件nginx反向代理和负载均衡完善登录功能 导入接口文档SwaggerSwagger常用注解 产品原型与技术选型 管理端原型图: 用户端原型图: 餐饮企业内部员工使用。 主要功能有: 模块描述登录…

onelist能让alist聚合网盘拥有海报墙

什么是 onelist ? onelist 是一个类似 emby 的专注于刮削 alist 聚合网盘形成影视媒体库的程序。 主要解决以下痛点: alist 挂载云盘后能在网页端看视频,却没有分类,没有海报墙;使用 webdav 挂载本地后,用…

马斯克星链与芯事:30亿美元炸出卫星互联网革命,GPU算力创无限可能

★卫星互联网;算力;卫星通信;互联网;低轨卫星互联网;5G基础设施;GPT-4 Turbo;算力;地面通信;液冷;水冷;AI服务器;东数西算&#xff1b…

2023年亚太杯数学建模A题水果采摘机器人的图像识别功能(免费思路)

中国是世界上最大的苹果生产国,年产量约为 3500 万吨。同时,中国也是世界上最大的苹果出口国,世界上每两个苹果中就有一个出口到国。世界上每两个苹果中就有一个来自中国,中国出口的苹果占全球出口量的六分之一以上。来自中国。中…

【数据结构】最小生成树(Kruskal算法)

一.基本思想 设无向连通网为G(V,E),令G的最小生成树为T(U,TE),其初态为UV,TE{},然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。若被考…

简述马尔可夫链【通俗易懂】

前言 马尔可夫链(Markov Chain)可以说是机器学习和人工智能的基石,在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用。 The future is independent of the past given the present 未来独立于过去&#xff…

不小心删除了Mac重要文档?试试这10个Mac数据恢复软件

您是否不小心删除了重要文件并需要可靠的解决方案?别再犹豫了!本文是您选择最佳 Mac 数据恢复软件的首选指南。我们的目标是为您提供做出明智决策和轻松找回丢失数据所需的工具和知识。 选择最佳 Mac 数据恢复软件:要考虑的因素 选择最佳 Ma…

高精度人像背景分割SDK技术解决方案

图像处理技术已经成为企业和个人生活中不可或缺的一部分,特别是在人像处理方面,如何准确、高效地将人物与背景分离,一直是一个技术难题。然而,美摄科技凭借其在AI深度学习领域的深厚积累,推出了一款高精度的人像背景分…

刷卡、扫码、插卡获取卡号,根据卡号请求数据;

业务需求&#xff1a;医院会进行刷卡 扫码 插卡等操作快速获取患者信息 一、刷卡和扫码 刷卡和扫码其实是同一种操作。刷卡/扫码和普通的键盘输入的区别就是&#xff1a;刷卡/扫码的速度快&#xff0c;而普通的键盘输入的速度慢。 <el-inputv-model"form.cardNo"…

【黑马甄选离线数仓day03_数仓设计和维度域开发】

1. 数仓基本概念 1- 什么是数据仓库呢? 存储数据的仓库, 主要用于存储过去历史发生过的数据,面向主题, 对数据进行统计分析的操作, 从而能够对未来提供决策支持 2- 数据仓库最大的特点是什么呢? 数据仓库既不生产数据, 也不消耗数据, 数据来源于各个数据源 3- 数据仓库的四…

uniapp打包的ipa上架到appstore的傻瓜式教程

​ 转载&#xff1a;uniapp打包的ipa上架到appstore的傻瓜式教程 uniapp打包 在HBuilder X编辑器中打开需要打包的项目&#xff0c;然后点击上面菜单栏中 发行 > 原生App-云打包&#xff0c;对以下弹出的弹窗进行内容填写 ​ 填写完成以后&#xff0c;点击打包操作 ​ ​ …

FreeSWITCH学习笔记:EventSocket

Event Socket命令最后需带有两个换行符。 api 执行API命令。阻塞。 1api API [ARG [ ...]] auth 内连模式下身份验证。需要第一个发送。 1auth PASSWORD bgapi 后台执行API命令。不阻塞。 1bgapi API [ARG [ ...]]2[Job-UUID: UUID] 返回带有Job-UUID。当API命令执行完成…

用自己热爱的事赚钱,是多么的幸福

挖掘天赋可能有些困难&#xff0c;但挖掘爱好就简单多啦&#xff01;最幸福的事情就是能用自己喜欢的事情赚钱。 我们要说的是一个博主&#xff0c;他非常喜欢骑自行车&#xff0c;虽然他的工作是在外贸公司做销售&#xff0c;但每当有空时&#xff0c;他都会骑自行车。而且他…

2023年亚太地区数学建模大赛 C 题

我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源&#xff08;非常规汽车燃料指汽油、柴油以外的燃料&#xff09;&#xff0c;将先进技术进行汽车动力控制和驱动相结合的汽车。新能源汽车主要包括四种类型&#xff1a;…