首页 > 其他分享 >Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式

Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式

时间:2023-08-04 19:02:33浏览次数:32  
标签:事务 RuntimeException -- Spring Transactional 回滚 方法 异常

实现方式:

:

在spring中有两种事务的实现方式,分别是编程式事务管理和编码式事务管理。

编程式事务一般使用的是TransactionTemplate工具类来实现

spring中使用的是@Transactional注解,可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性。

参数描述:

  • readOnly 该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
  • rollbackFor 该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
  • rollbackForClassName 该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
  • noRollbackFor 该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
  • noRollbackForClassName 该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
  • propagation 该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
  • isolation 该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
  • timeout 该属性用于设置事务的超时秒数,默认值为-1表示永不超时

:

事务的隔离级别

隔离级别指的是若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:

Spring事务的隔离级别

1.ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应。

 2.ISOLATION_READ_UNCOMMITTED:

这是事务最低的隔离级别,它充许令外一个事务可以读取到另一个事务未提交的事务记录。换句话说,a transaction can read the data that is still uncommitted by other transactions。这是Spring事务最弱的隔离级别。见下面的图,事务A开启,写入一条记录,这时候,事务B读入数据,读到了这条记录,但是,之后事务A回滚。因此,事务B读到的数据不是有效的(the database is in an invalid state)。这种情况称为脏读(dirty read)。除了脏读的问题,READ_UNCOMMITTED还可能出现non-repeatable read(不可重复读)和phantom read(幻读)的问题。

Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式_回滚

 3.ISOLATION_READ_COMMITTED:

换句话说,a transaction can only read the committed data, and it can’t read the uncommitted data.因此,dirty read的情况不再发生,但可能会出现其他问题。

在事务A两次读取的过程之间,事务B修改了那条记录并进行提交。因此,事务A前后两次读取的记录不一致。这个问题称为non-repeatable read(不可重复读)。(两次读取的记录不一致,重复读取就会发现问题。)

除了non-repeatable read的问题,READ_COMMITTED还可能发生phantom read的问题。

Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式_回滚_02

4.ISOLATION_REPEATABLE_READ:

一个事务可以多次从数据库读取某条记录,而且多次读取的那条记录都是一致的,相同的。这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。事务A两次从数据库读取一系列记录,期间,事务B插入了某条记录并提交。事务A第二次读取时,会读取到事务B刚刚插入的那条记录。在事务期间,事务A两次读取的一系列记录不一致,这个问题称为phantom read。

Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式_隔离级别_03

 5.ISOLATION_SERIALIZABLE

其中的一些概念的说明:

(1)脏读:读到了其他事务还没有提交的数据。

(2)不可重复读:对某数据进行读取,发现两次读取的结果不同,也就是说没有读到相同的内容。这是因为有其他事务对这个数据同时进行了修改或删除。

(3)幻读:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 更改或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候发现会有 N+M 条数据,产生了幻读。

spring事务传播行为详解

前言

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为。这是Spring为我们提供的强大的工具箱,使用事务传播行可以为我们的开发工作提供许多便利。但是人们对他的误解也颇多,你一定也听过“service方法事务最好不要嵌套”的传言。要想正确的使用工具首先需要了解工具。

我们可以使用propagation 来对事务的传播行为进行声明式的设定

一、什么是事务传播行为?

事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。

用伪代码说明:

public void methodA(){
    methodB();
    //doSomething
 }
 
 @Transaction(Propagation=XXX)
 public void methodB(){
    //doSomething
 }

代码中methodA()方法嵌套调用了methodB()方法,methodB()的事务传播行为由@Transaction(Propagation=XXX)设置决定。这里需要注意的是methodA()并没有开启事务,某一个事务传播行为修饰的方法并不是必须要在开启事务的外围方法中调用。

二、Spring中七种事务传播行为

Spring事务 --》@Transactional参数、事务实现方式、隔离级别、传播方式_隔离级别_04

是否受当前方法回滚影响?

自己会生成事务的:

1.PROPAGATION_REQUIRED:父有事务则父子同心型,父没事务则靠自己。

2.PROPAGATION_REQUIRES_NEW:父子决裂型,各花各的。

3.PROPAGATION_NESTED:自力更生,父债子还型。

自己不会生成事务的:

4.PROPAGATION_SUPPORTS:啃老型,自己有没有事务全靠爹,爹有就花爹的,没有就不花穷着。

5.PROPAGATION_MANDATORY:大冤种型,靠爹的事务,爹没有事务还要报异常。

5.PROPAGATION_NOT_SUPPORTED:不要家产,就要吃土型,不管爹有没有事务,反正我不要

7.PROPAGATION_NEVER:无能逆子型,自己没有事务也不许爹有,否则报异常

三、REQUIRED,REQUIRES_NEW,NESTED异同

NESTED和REQUIRED修饰的内部方法都属于外围方法事务,如果外围方法抛出异常,这两种方法的事务都会被回滚。但是REQUIRED是加入外围方法事务,所以和外围事务同属于一个事务,一旦REQUIRED事务抛出异常被回滚,外围方法事务也将被回滚。而NESTED是外围方法的子事务,有单独的保存点,所以NESTED方法抛出异常被回滚,不会影响到外围方法的事务。

NESTED和REQUIRES_NEW都可以做到内部方法事务回滚而不影响外围方法事务。但是因为NESTED是嵌套事务,所以外围方法回滚之后,作为外围方法事务的子事务也会被回滚。而REQUIRES_NEW是通过开启新的事务实现的,内部事务和外围事务是两个事务,外围事务回滚不会影响内部事务。

四、三种Transactional不回滚问题

1.检查你方法是不是public的,public方法的Transactional注解才是有效的,才能控制事务。

2.Spring默认只对UnChecked异常(RuntimeException)回滚,对于Checked(Exception)异常不回滚。

你的异常类型是Checked异常。如果想check异常也想回滚怎么办?

(1)注解上加rollbackFor=Exception.class

(2)对异常进行转换,转换成RuntimeException或自定义继承RuntimeException的异常

3.同一个类中的方法调用,内部方法的事务是没有效果。

如方法A没加事务,方法B中加了事务(不管加的是什么类型的事务)。方法A调用方法B,这样方法B中的事务是无效的。因为AOP只对A方法进行处理了,而不会对内部的B方法进行处理。

五、异常:Transaction rolled back because it has been marked as rollback-only原因

1.捕获后又抛出了不回滚的异常(默认RuntimeException才回滚,而Exception不回滚)。

2.Propagation.REQUIRED A方法调用 Propagation.REQUIRED B方法,如果捕获了B方法中的异常没有抛出 或 捕获后又抛出了不回滚的异常(默认Exception不回滚)。

标签:事务,RuntimeException,--,Spring,Transactional,回滚,方法,异常
From: https://blog.51cto.com/u_16173281/6966245

相关文章

  • Apipost三方消息通知,接口变更不用愁
    Apipost致力于为开发者提供更全面的API管理功能。而最近,Apipost又新增了一个非常实用的功能:第三方消息推送。这个功能可以帮助开发人员及时了解API的变更情况,从而更好地管理和优化自己的API。具体来说,Apipost的第三方消息推送功能可以通过配置飞书群聊机器人webhook地址来实现API变......
  • RunnerGo条件控制器使用方法
    在做性能测试时我们需要根据业务需求、业务场景来配置测试脚本,举个例子:在登录注册场景中,可能会有账号密码全部正确、账号格式错误、密码错误等多种情况,这里的“登录/注册”事件可以视为一个场景。一个真实业务中的场景,不仅是独立接口的串联,还会涉及到条件分支、参数提取、断言等一......
  • 从盒马“高山夏菜”热卖,看商业与公益的可持续路径
    从盒马“高山夏菜”热卖,看商业与公益的可持续路径很多人只听过“南水北调”,但对“西菜东运”“西菜南调”相对比较陌生。每到夏季高温天,国内东南部地区的本地蔬菜因受到环境影响减产,就会进入传统意义上的“伏缺”季,怎么弥补蔬菜市场的空缺?一批自然生长在高海拔地区的夏菜成为洛很好......
  • JVM零基础到高级实战之Java内存区域虚拟机栈
    前言JVM零基础到高级实战之Java内存区域虚拟机栈JVM内存模型之虚拟机栈虚拟机栈是什么?用于作用于方法执行的一块Java内存区域为什么要有虚拟机栈?每个方法在执行的同时都会创建一个栈帧(StackFramel)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至......
  • HttpClient Https请求 基础连接已经关闭,发送时发生错误
    可能有以下几个原因:证书问题:服务端证书无效或者客户端不信任服务器证书会导致握手失败。你需要检查服务端证书是否有效,是否由受信任的证书颁发机构(CA)签署。TLS版本不兼容:服务端只支持较新版本的TLS,而客户端使用的.NET版本较旧,其中包含的TLS版本与服务端不兼容。尝试升级.......
  • 棱镜七彩正式加入龙蜥社区安全联盟(OASA)
    近日,龙蜥社区安全联盟(OASA)正式成立,棱镜七彩成为该联盟成员单位。龙蜥社区安全联盟是促进产业合作的非营利组织,致力于打造中立开放、聚焦操作系统信息安全的交流平台,推进龙蜥社区乃至整个产业安全生态的体系化建设。作为龙蜥社区安全联盟(OASA)成员单位,棱镜七彩将积极参与社区安全技术......
  • SQL Server实现mysql中的group_concat功能
    mysql中的group_concat函数的功能将groupby产生的同一个分组中的值连接起来,返回一个字符串结果。group_concat函数首先根据groupby指定的列进行分组,将同一组的列显示出来,并且用分隔符分隔。由函数参数(字段名)selectgroup_concat(emp_name)fromemp;语法:group_concat([distin......
  • std::shared_ptr 线程安全方面的思考
    一直惦记着std::shared_ptr线程安全的问题,看了些文章后,又怕过段时间忘记了,遂记录下来std::shared_ptr的线程安全问题主要有以下两种:引用计数的加减操作是否线程安全std::shared_ptr修改指向时是否线程安全第一个问题的答案:是线程安全的,因为是原子操作注意:引用计数这......
  • 使用PaddleOCR在Ubuntu上实现一键截屏OCR提取文本
    转自:https://aistudio.baidu.com/aistudio/projectdetail/5665249一、项目简介1.1简要说明最近在折腾Ubuntu,有一个截屏然后OCR提取文本的应用需求。在Windws上这样的工具很好找,但是在Linux没有现成的软件可用,得自己解决。网上流行的方案是使用tesseract,试了一下,效果并不......
  • 公众号添加附件,图文附件,三步轻松搞定,太省事了!
    在当今数码产品、游戏、软件app、服务产品等种类繁多的市场中,如何快速、简便地添加图文附件成了一个亟待解决的问题。而“图文附件”这个公众号,通过三步就能轻松添加图文附件,让这个问题迎刃而解。让我们一起来了解一下吧。 在第一次使用“图文附件”时,需要关注公众号。进入公众......