spring - tx 事务的使用(事务的传播行为是啥)

补充:事务的传播行为是啥

事务的传播行为:指的是,当一个事务方法被另一个事务方法调用时,这个被调用的事务方法应该如何进行,
简单来说,它决定了事务方法是在调用者的事务中运行,还是为自己开启一个新的事务运行。

在Spring框架中,
事务的传播行为,是通过@Transactional注解的propagation属性来配置的,
Spring定义了七种类型的事务传播行为,每种行为都有其特定的用途和场景。其中最常见的包括:

  • PROPAGATION_REQUIRED(默认值):如果,父方法有事务,我们就加入到父方法的事务,最终是同一个事务
    如果,父方法没有事务,就新建自己独立的事务
  • PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED行为。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

这些传播行为提供了灵活的事务管理策略,可以根据具体的应用场景和需求来选择合适的传播行为。通过合理配置事务的传播行为,可以确保数据的一致性和完整性,同时提高系统的性能和可靠性。

Spring事务管理器

1、Spring声明式事务对应依赖

	spring-tx:包含声明式事务实现的基本规范(事务管理器规范接口 和 事务增强等等)spring-jdbc:包含DataSource方式事务管理器实现类 DataSourceTransactionManagerspring-orm:包含其他持久层框架的事务管理器实现类,如:Hibernate/Jpa等

2、spring声明式事务对应事务管理器接口

							TransactionManager 顶层接口||PlatformTransactionManager 接口|			        	||	         			|DataSourceTransactionManager实现类	  HibernateTransactionManager实现类Spring框架中,"TransactionManager"是一个顶层接口,用于,定义事务管理行为的顶层接口,提供了开始事务、提交事务、回滚事务等方法的定义。作用:定义了事务管理的标准行为,可以有不同的实现类来实现具体的事务管理逻辑。"PlatformTransactionManager"Spring框架中的事务管理平台接口,定义了对事务进行管理的方法。作用:作为事务管理的核心接口,定义了事务的开始、提交、回滚等操作,具体的事务管理器实现类需要实现这些方法。"DataSourceTransactionManager"Spring框架中,用于基于数据源的事务管理的实现类,用于,管理JDBC事务。作用:通过数据源管理事务,可以在Spring应用中使用JDBC进行数据库访问,并通过该事务管理器实现事务管理。"HibernateTransactionManager"Spring框架中,用于与Hibernate集成的事务管理器实现类,用于,管理Hibernate事务。作用:通过与Hibernate集成,可以在Spring应用中使用Hibernate进行ORM操作,并通过该事务管理器实现事务管理。

我们现在使用的事务管理器是:org.springframework.jdbc.datasource.DataSourceTransactionManager

将来整合JDBC方式、JdbcTemplate方式、Mybatis方式的事务实现。

3、DataSourceTransactionManager类中主要方法

	doBegin():开启事务doSuspend():挂起事务doResume():恢复挂起的事务doCommit():提交事务doRollback():回滚事务

举个例子

1、数据库的配置文件:src/main/resources/jdbc.properties

	atguigu.url=jdbc:mysql:///my_studyatguigu.driver=com.mysql.cj.jdbc.Driveratguigu.username=rootatguigu.password=root

2、配置类:src/main/java/com.atguigu.config/JavaConfig.java

package com.atguigu.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;@Configuration  1、说明这是个配置类
@ComponentScan("com.atguigu")  2、包扫描
@PropertySource("classpath:jdbc.properties")  3、引入配置文件
@EnableAspectJAutoProxy  开启aspectj注解的支持
@EnableTransactionManagement  开启事务注解的支持
public class JavaConfig {这里读取 src/main/resources/jdbc.properties文件的数据库相关配置@Value("${atguigu.driver}")private String driver;@Value("${atguigu.url}")private String url;@Value("${atguigu.username}")private String username;@Value("${atguigu.password}")private String password;4、druid连接池实例化,"DruidDataSource"实现了"DataSource"接口,所以这里用 public DataSource dataSource()@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}5、jdbcTemplate@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}@Beanpublic TransactionManager transactionManager(DataSource dataSource){* 内部需要进行事务的操作,基于的连接池DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();* 需要连接池对象dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}

3、dao层:src/main/java/com.atguigu.dao/StudentDao.java

package com.atguigu.dao;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;@Repository
public class StudentDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void updateNameById(String name, Integer id){String sql = "update my_user set name = ? where id = ?";int rows = jdbcTemplate.update(sql, name, id);}public void updatePloneById(String plone, Integer id){String sql = "update my_user set plone = ? where id = ?";int rows = jdbcTemplate.update(sql, plone, id);}
}

4、service层:src/main/java/com.atguigu.service/StudentService.java


package com.atguigu.service;import com.atguigu.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.io.FileInputStream;
import java.io.FileNotFoundException;@Service
public class StudentService {@Autowiredprivate StudentDao studentDao;* 怎样添加事务呢?使用 "@Transactional"注解 即可* 这个"@Transactional"注解在哪加呢?方式1、加到某个方法上,那么,这个方法就有事务了方式2、加到某个类上,那么,这个类的所有方法就都有事务了* "@Transactional"注解,的属性1、只读模式只读模式,可以提升查询事务的效率,推荐事务中只有查询代码时,使用只读模式默认情况下(源码):boolean readOnly() default false解释,一般情况下,都是直接把 "@Transactional"注解 加到类上,则,这个类的所有方法,就都有事务了,但是,你可以在查询方法上再加一次 "@Transactional"注解,并且设置只读模式,提高效率2、超时时间事务在执行过程中,可能会由于某些问题导致卡住,从而长时间占用数据库资源,而长时间占用数据库资源,大概率是因为程序出现了问题(可能是Java程序、Mysql数据库、网络连接等问题)此时,这个很可能出现问题的程序就应该被回滚,撤销他已做的操作,事务结束,把资源让出来,让其他程序可以正常执行总之,就是,超时回滚、释放资源默认,永不超时(值是-1)设置 "timeout = 秒数",超时后,就会回滚事务和释放异常,超时的异常是:"TransactionTimedOutException"如果,类上设置了 "@Transactional"注解 和 这个"timeout"属性,并且,方法上也设置了 "@Transactional"注解,但是没有设置"timeout"属性,那么,此时,"方法上的timeout值是 默认值 -1"3、指定异常回滚 和 指定异常不回滚默认情况下:发生运行时异常,才会回滚我们可以指定Exception异常来控制所有异常都会滚rollbackFor = Exception.class,意思是:所有的异常都回滚noRollbackFor = FileNotFoundException.class,意思是:指定FileNotFoundException异常不回滚@Transactional(timeout = 3, rollbackFor = Exception.class, noRollbackFor = FileNotFoundException.class)public void changeInfo() throws FileNotFoundException {studentDao.updatePloneById("1390002", 1);加这句代码,是为了测试事务是否加上了,int i = 1/0; 这句代码本身是会报错的,因为,有事务的话,即使 int i = 1/0; 这句代码上面的代码没有错,但是 int i = 1/0; 报错了,会造成,回滚,所以整个方法里的代码都不会生效。但是,如果没有事务的话,int i = 1/0; 这句代码上面正确的代码会执行生效的// int i = 1/0;//        try {
//            Thread.sleep(5000); // 等5秒,为了测试 timeout这个属性
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }测试:异常回滚new FileInputStream("xxx");System.out.println("----------------------------");studentDao.updateNameById("springtx-改名", 2);}事务传播行为:声明两个独立修改数据库的事务业务方法propagation = Propagation.REQUIRED意思是:如果,父方法有事务,我们就加入到父方法的事务,最终是同一个事务如果,父方法没有事务,就新建自己独立的事务propagation = Propagation.REQUIRES_NEW意思是:不管父方法是否有事务,我都是独立的事务@Transactional(propagation = Propagation.REQUIRES_NEW)public void changePlone(){studentDao.updatePloneById("1390004", 1);}@Transactional(propagation = Propagation.REQUIRES_NEW)public void changeName(){studentDao.updateNameById("spring-tx-嘎嘎", 2);int i = 1 / 0; // 报错}}

5、最后,写一个测试类:src/test/com.atguigu.test/SpringTest.java

package com.atguigu.test;import com.atguigu.config.JavaConfig;
import com.atguigu.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;import java.io.FileNotFoundException;@SpringJUnitConfig(JavaConfig.class)
public class SpringTxTest {@Autowiredprivate StudentService studentService;@Testpublic void test() throws FileNotFoundException {studentService.changeInfo();}@Testpublic void test1(){studentService.changePlone();  会改变数据库的内容studentService.changeName();  不会改变数据库的内容,因为报错,导致事务回滚了}@Test@Transactional  即使父方法这里加上"@Transactional",但是下面着2个方法的"propagation = Propagation.REQUIRES_NEW"所以,结果如下:public void test2(){studentService.changePlone();  会改变数据库的内容studentService.changeName();  不会改变数据库的内容,因为报错,导致事务回滚了}}

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

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

相关文章

宝剑锋从磨砺出,透视雀巢咖啡品牌焕新与产品升级的想象力

自1989年进入中国市场以来,陪伴着国内咖啡行业由启蒙期走向兴盛期的雀巢咖啡,始终坚持以消费者高品质、个性化需求为本位,在保有独特性的基础上持续创新,实现了从无到有的攻克与突破。 近日,深耕中国三十六载的雀巢咖…

康耐视visionpro-CogCreateLinePerpendicularTool操作操作工具详细说明

CogCreateLinePerpendicularTool]功能说明: 创建点到线的垂线 CogCreateLinePerpendicularTool操作说明: ①.打开工具栏,双击或点击扇标拖拽添加CogCreateLinePerpendicularTool ②.添加输入源:右键“链接到”或以连线拖 拽的方式…

Java代码基础算法练习-圆的面积-2024.04.17

任务描述&#xff1a; 已知半径r&#xff0c;求一个圆的面积(保留两位小数)&#xff0c;其中 0 < r < 5&#xff0c;PI 3.14&#xff0c;圆面积公式: PI * r * r 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;// 已知半径…

【前端】1. HTML【万字长文】

HTML 基础 HTML 结构 认识 HTML 标签 HTML 代码是由 “标签” 构成的. 形如: <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. <body> 为开始标签, </body> 为结束标签.少数标签只有开始标签, 称为 “单标签”.开始标签和…

Linux-时间同步服务器

1. (问答题) 一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com 编写脚本文件 #!/bin/bash hostnamectl hostname ntp_server.example.com cd /etc/NetworkManager/system-connections/ rm -fr * cat > eth0.nmconnection <&…

【编译原理】02词法分析(1)

接上篇 &#xff1a;【编译原理】01引论 词法分析是编译过程中将字符流转换成为符号流的一个工作阶段&#xff0c;是编译的第一步工作&#xff0c;其后续工作是语法分析。 词法分析的输入是源代码&#xff1b; 词法分析的输出是符号流&#xff1b; 词法分析需要识别词法错误&am…

STM32 软件I2C方式读取MT6701磁编码器获取角度例程

STM32 软件I2C方式读取MT6701磁编码器获取角度例程 &#x1f4cd;相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》&#x1f33f;《Arduino通过I2C驱动MT6701磁编码器并读取角度数据》&#x1f530;MT6701芯片和AS5600从软件读取对比&#xff0c;只是读取的寄存器和…

代码随想录算法训练营第56天| 583. 两个字符串的删除操作|72. 编辑距离|编辑距离总结篇

代码随想录算法训练营第56天| 583. 两个字符串的删除操作|72. 编辑距离|编辑距离总结篇 详细布置 583. 两个字符串的删除操作 本题和动态规划&#xff1a;115.不同的子序列 相比&#xff0c;其实就是两个字符串都可以删除了&#xff0c;情况虽说复杂一些&#xff0c;但整体思…

【Redis 神秘大陆】009 案例实践进阶

九、案例实践&进阶方案 9.1 本地缓存组件选型 使用缓存组件时需要重点关注集群方式、集群、缓存命中率。 需要关注集群组建方式、缓存统计&#xff1b;还需要考虑缓存开发语言对缓存的影响&#xff0c;如对于JAVA开发的缓存需要考虑GC的影响&#xff1b;最后还要特别关注…

SQL优化——核心概念

文章目录 1、基数(数据分布)2、选择性3、直方图&#xff08;HISTOGRAM&#xff09;4、回表&#xff08;TABLE ACCESS BY INDEX ROWID&#xff09;5、集群因子&#xff08;CLUSTERING FACTOR&#xff09;6、表与表之间关系 1、基数(数据分布) 某个列唯一键&#xff08;Distinct…

springboot整合dubbo实现RPC服务远程调用

一、dubbo简介 1.什么是dubbo Apache Dubbo是一款微服务开发框架&#xff0c;他提供了RPC通信与微服务治理两大关键能力。有着远程发现与通信的能力&#xff0c;可以实现服务注册、负载均衡、流量调度等服务治理诉求。 2.dubbo基本工作原理 Contaniner:容器Provider&#xf…

[AI]-(第0期):认知深度学习

深度学习是一种人工智能&#xff08;AI&#xff09;方法&#xff0c;用于教计算机以受人脑启发的方式处理数据。 深度学习模型可以识别图片、文本、声音和其他数据中的复杂模式&#xff0c;从而生成准确的见解和预测。 您可以使用深度学习方法自动执行通常需要人工智能完成的…

【C++】set 类 和 map 类

1. 关联式容器 关联式容器也是用来存储数据的&#xff0c;与序列式容器不同的是&#xff0c;其里面存储的是<key, value>结构的 键值对&#xff0c;在数据检索时比序列式容器效率更高 2. 键值对 用来表示具有一一对应关系的一种结构&#xff0c;该结构中一般只包含…

Pytorch(GPU版本)简介、安装与测试运行

目录 Pytorch简介Pytorch安装查看CUDA版本Pytorch命令安装Pytorch测试运行Pytorch简介 PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。 2…

Linux进阶篇:Centos7安装与配置mysql(rpm安装方式)

Linux服务搭建篇&#xff1a;Centos7安装与配置mysql&#xff08;rpm安装方式&#xff09; MySQL是一个开源的关系型数据库管理系统&#xff0c;由瑞典MySQL AB公司开发&#xff0c;现在属于Oracle公司。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在WEB应用方面&am…

【架构-14】数据库性能优化方式

数据库出现性能瓶颈对外的表现为&#xff1a; 大量请求阻塞SQL操作变慢存储出现问题 为解决上述出现的问题&#xff0c;因此推出了一系列的数据库性能优化方式。 数据库性能优化是提高数据库系统性能和响应时间的关键任务。以下是一些常见的 数据库性能优化方式&#xff1a; …

锂电池充放电管理-单片机通用

锂电池充放电管理-单片机通用 一、锂电池充放电检测的原理二、power.c的实现三、power.h的实现四、锂电池检测和充电电路 一、锂电池充放电检测的原理 ①两节锂电池通过电阻分压检测ADC&#xff0c;再根据电压划分电量等级&#xff1b;②充电使用的是锂电池充电IC方案&#xf…

【问题解决分享】银河麒麟高级服务器操作系统oom分析

1.问题现象描述 服务器数据库被oomkill掉&#xff0c;但是mem查看只占用了不到60%。 2.问题分析 2.1.oom现象分析 从下面的日志信息&#xff0c;可以看到chmod进程是在内核采用GFP_KERNEL|__GFP_COMP分配order3也就是2的3次方&#xff0c;8个连续页的时候&#xff0c;因进入…

Hadoop大数据处理技术-安装配置篇

2024/4/16 ​Hadoop学习前的准备 1&#xff09;首先安装虚拟机 VMWare 虚拟机&#xff1a;因为它不是一个硬件 而是用软件做出来的 模拟真机 所以叫做虚拟机 但实际上它里面也可以安装Linux和Windows 实际它的实现 虚拟机中想要实现某个操作时 将需求发给Windows 调用Windo…

十大排序——7.希尔排序

下面我们来看一下希尔排序 目录 1.介绍 2.代码实现 3.总结与思考 1.介绍 希尔排序是插入排序的一种优化&#xff0c;可以理解为是一种分组的插入排序。 希尔排序的要点&#xff1a; 简单来说&#xff0c;就是分组实现插入&#xff0c;每组元素的间隙称为gap&#xff0c;…