Spring事务和事务传播机制

1.事务

在学习数据库时,已经接触过这个概念,事务指的是一组操作的集合,是一个不可分割的操作.事务会把所有的操作作为一个整体,一起向数据库提交或者撤销操作,这组操作要么同时成功,要么同时失败.事务的操作主要有三步,1.开启事务 start transaction/begin(一组操作开启事务) 2.提交事务:commit(这组操作全部成功,提交事务) 3.回滚事务:rollback(这组操作中间出现任何一个异常,回滚事务).

2.Spring中事务的实现 Spring中的事务操作分为两类:1.编程式事务(手动写代码操作事务) 2.声明式事务(利用注解自动开启和提交事务),在数据库中,建立下面的表:分为用户表和日志表,用户注册时在日志表中插入一条数据.分别建立对应的类和mapper层,service层,controller层.Controller层的代码如下:Service层的代码如下:mapper层的代码如下:下面介绍Spring中的声明式事务@Transactional,在需要事务的方法上添加@Transactional注释就可以实现.正常情况下,传入name和password查看数据库,发现插入正常.现在修改程序使之出现异常,出现异常后,数据库就不能新增用户信息.这里设置一个算数异常,在没有添加@Transactional的情况之下,即时发生异常,数据还是会插入.这里抛出了异常,查看数据库还是插入了数据这里就需要使用@Transactional.@Transactional的作用:@Transactional可以用来修饰方法或者类:修饰方法时:只有修饰public方法才会生效(修饰其他方法时不会报错,也不生效);修饰类时:对@Transactional修饰的类中的所有的public方法都生效.方法/类被@Transactional注释修饰时,在目标方法开始执行之前,会自动开启事务,方法执行结束之后,会自动提交事务.如果在方法执行过程中,出现异常,且异常未被捕获,就进行事务的回滚操作.如果异常被程序捕获,方法就被认为是成功执行,依然会提交事务.修改上述代码,再一次进行测试,观察用户信息是否会被写入数据库. 这里没有进行异常捕获和抛出,所以会进行回滚,Spring的事务管理依赖于未被捕获的异常来触发回滚机制.这里对异常进行捕获,注册一个名为boluo的用户,可以发现,虽然程序出错了,但是由于异常被捕获了.依旧可以成功写入数据库在对异常进行捕获之后,如果需要事务进行回滚,有下面两种方式:1.重新抛出异常2.手动回滚事务,如下:

3.Transactional详解.@Transactional注解当中的三个常见的属性:

1.rollbackFor:异常回滚属性.指定能够触发事务回滚的异常类型,可以指定多个异常类型. 2.lsolation:事务的隔离级别.默认值为Isolation.DEFAULT 3.propagation:事务的传播机制,默认值为Propagation.REQUIRED

3.1 rollbackFor @Transactional默认只在遇到运行时异常和Error时才会进行回滚,非运行时异常不回滚.即Exception的子类中,除了RuntimeException以及子类.这里设置一个IO异常插入一个名为fanqieyu的用户,查看数据库,由于IO异常既不属于RuntimeException和Error.所以不会进行事务的回滚.如果这里要设置将所有的异常都进行回滚,需要配置@Transactional中的rollbackFor属性,通过rollbackFor这个属性指定出现何种类型的异常时进行事务的回滚.当然也可以这样设置rollbackFo会在默认的基础上增加指定的回滚类型. 结论:在Spring的事务管理中,默认只在遇到运行时异常RuntimeException和Error时来会进行回滚.如果需要回滚指定类型的异常,可以通过rollbackFor属性来指定. 3.2事务的传播机制 事务的传播机制就是:多个事务方法存在调用关系时,事务是如何在这些方法之间进行传播的,比如有两个方法A,B都被@Transactional修饰,A方法调用B方法,A方法运行时会开启一个事务,当A调用B时,B方法本身也有事务,此时B方法运行时,是加入A的事务还是新建一个事务呢?这个就涉及到了事务的传播机制.一个公司的流程管理,执行任务之前,需要先写执行文档,任务执行结束,再写总结报告.A,B部门的流程相同:这里A有一项工作,需要B的帮助,此时B是直接使用A的文档还是新建一个文档呢?事务传播机制解决的是一个事务在多个方法中传递的问题这里主要介绍两种事务的传播机制:1.REQUIRED(默认值) 2.REQULIRES_NEW 1.REQUIRED(加入事务),@Transactional注解支持事务传播机制的设置,通过propagation属性来指定传播行为.Propagation.REQUIRED:默认的事务传播机制,如果当前存在事务,则加入事务.如果当当前没有事务,则创建一个事务.下面的例子,用户注册,插入一条数据,记录操作日志,插入一条异常数据.这个流程,访问p1,开启一个事务,先执行userService的方法,执行成功(和p1使用的是一个事务),记录操作日志,插入一条数据(出现异常,执行失败)(由于这里已经有事务了,则加入这个事务),因为日志这里出现了异常,由于日志和插入用户数据这里使用的是一个事务,所以都会发生回滚.

2.REUQIRES_NEW(新建事务),Propagation.REQUIRES_NEW:创建一个新的事务.如果当前存在事务,则把当前事务挂起,也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的方法都会新开启自己的事务,且开启的事务互相独立,互不干扰,将上述UserService和LogService中相关方法事务传播机制改为Propagation.REQUIRES_NEW这里发生异常之后,由于这里设置为了新建事务,所以PropagationController.r3()事务:因为异常传播回滚.UserService.insertUser()事务:因运行时异常回滚 LogService.insertLog()事务:不会回滚,因为在调用UserService.insertUser()时就发生了异常,所以没有执行到 LogService.insertLog(),所以没有创建事务,也就谈不到回滚了.

相关推荐
liliangcsdn14 分钟前
mac neo4j install & verifcation
数据库·neo4j
Cyanto30 分钟前
MyBatis-Plus高效开发实战
java·开发语言·数据库
-XWB-1 小时前
【Oracle】套接字异常(SocketException)背后隐藏的Oracle问题:ORA-03137深度排查与解决之道
数据库·oracle
睿思达DBA_WGX1 小时前
由于主库切换归档路径导致的 Oracle DG 无法同步问题的解决过程
运维·数据库·oracle
懂得节能嘛.1 小时前
【SpringAI实战】ChatPDF实现RAG知识库
java·后端·spring
探索java1 小时前
Spring 解析 XML 配置文件的过程(从读取 XML 到生成 BeanDefinition)
xml·java·spring·xmlbeanfactory
!chen2 小时前
Oracle 19.20未知BUG导致oraagent进程内存泄漏
数据库·oracle·bug
DarkAthena2 小时前
【GaussDB】构建一个GaussDB的Docker镜像
数据库·docker·gaussdb
祁思妙想3 小时前
add新增管理员功能、BaseController类的简介--------示例OJ
数据库·windows
技术卷3 小时前
详解力扣高频SQL50题之1164. 指定日期的产品价格【中等】
sql·leetcode·oracle