JAVA应用】事务的传播机制是什么?有那几种?

2020-09-04 15:43发布

6条回答
流流流年
2楼 · 2020-09-04 17:43
  1. REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。

  2. SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。

  3. MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。

  4. REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。

  5. NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。

  6. NEVER:无事务执行,如果当前有事务则抛出Exception。

  7. NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

糖包啊肉包
3楼 · 2021-06-28 15:29

1.首先来说什么是事务:

  事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败)。

  数据库向用户提供保存当前程序状态的方法,叫事务提交(commit;当事务执行过程中,使数据库忽略当前的状态并回到前面保存的状态的方法叫事务回滚(rollback

2.事务的传播机制

  以spring的事务传播机制为例子:

  Spring事务机制主要包括声明式事务编程式事务,此处侧重讲解声明式事务,编程式事务在实际开发中得不到广泛使用,仅供学习参考。

  Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的try…catch…finally代码。我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。

spring在TransactionDefinition接口中定义了七个事务传播行为:


    • propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。

    • propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。

    • propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。

    • propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。

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

    • propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。

    • propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

爱梦 - 拿来吧你
4楼 · 2021-06-29 09:27

7种事务传播机制:

1、PROPAGATION_REQUIRED

注解用法如:@Transactional (propagation = Propagation.REQUIRED )

默认的spring事务传播级别,使用该级别的特点是,如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行。所以这个级别通常能满足处理大多数的业务场景。

比如,ServiceB.methodB的事务级别定义为 PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA
的事务内部,就不再起新的事务;

而假如ServiceA.methodA运行的时候发现自己没有在事务中,它就会为自己分配一个事务。这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚。

2、PROPAGATION_SUPPORTS

该传播级别的特点是,如果上下文存在事务,则支持事务加入事务,如果没有事务,则使用非事务的方式执行。所以说,并非所有的包在transactionTemplate.execute中的代码都会有事务支持。这个通常是用来处理那些并非原子性的非核心业务逻辑操作。

应用场景较少。

3、PROPAGATION_MANDATORY

该级别的事务要求上下文中必须要存在事务,否则就会抛出异常!

配置该方式的传播级别是有效的控制上下文调用代码遗漏添加事务控制的保证手段。

比如一段代码不能单独被调用执行,但是一旦被调用,就必须有事务包含的情况,就可以使用这个传播级别。

4、PROPAGATION_REQUIRES_NEW

该传播级别的特点是,每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。

比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,
那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,
它才继续执行。它与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在
两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,
如果它抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

5、PROPAGATION_NOT_SUPPORTED

该传播属性不支持事务,该级别的特点就是上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。

这个级别有什么好处?可以帮助你将事务极可能的缩小。因为一个事务越大,它存在的风险也就越多。所以在处理事务的过程中,要保证尽可能的缩小范围。

比如一段代码,是每次逻辑操作都必须调用的,比如循环1000次的某个非核心业务逻辑操作。这样的代码如果包在事务中,势必造成事务太大,导致出现一些难以考虑周全的异常情况。所以这个事务这个级别的传播级别就派上用场了。用当前级别的事务模板包起来就可以了。

比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,
那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而它以非事务的状态运行完,再继续ServiceA.methodA的事务。

6、PROPAGATION_NEVER

不能在事务中运行。该传播级别要求上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制停止执行!

假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER ,那么ServiceB.methodB就要抛出异常了。

7、PROPAGATION_NESTED

理解Nested的关键是savepoint。
它与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与它的父事务相互独立,
而Nested的事务和它的父事务是相依的,它的提交是要等和它的父事务一块提交的。也就是说,如果父事务最后回滚,它也要回滚的。

而Nested事务的好处是它有一个savepoint。


天天
5楼 · 2021-07-05 16:24

事务:程序中一系列严密的操作,所有操作执行必须同时成功,或者同时撤销

spring中的事务转播机制:

1、PROPAGATION_REQUIRED:是否包含,否则重新创建一个事务

2、PROPAGATION_SUPPORTS:是否在当前事务中,在以事务的形式运行;否则,以非事务的形式运行

3、PROPAGATION_MANDTORY:只能被父事务调用,否则抛出异常

4、PROPAGATION_REQUIRS_NEW:比PROPAGATION_REQUIRED优先级高

5、PROPAGATION_NOT_SUPPORTED:当前不支持事务

6、PROPAGATION_NEVER:不能再事务中运行

7、PROPAGATION_NESTED:该事务机制没有再EJB标准中定义


水默
6楼 · 2021-07-06 10:43
传播机制作用
PROPAGATION_REQUIREDSpring默认的传播机制,ServiceA.method()-->ServiceB.method,若A和B都声明了事务,则B不会独立开启事务,将B的事务放到A中一起执行,A和B任意一个报错都会整体回滚
PROPAGATION_REQUES_NEWServiceB会强制开启一个新的事务,执行的时候ServiceA会卡主等待B执行完毕之后再继续。若A报错,B不受影响,B报错,A可以选择性的回滚或者提交
PROPAGATION_SUPPORT如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务
PROPAGATION_NOT_SUPPORT该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码
PROPAGATION_NEVER该传播机制不支持外层事务,即如果外层有事务就抛出异常
PROPAGATION_MANDATORY与NEVER相反,如果外层没有事务,则抛出异常
PROPAGATION_NESTED该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。


征戰撩四汸
7楼 · 2021-11-03 15:47

REQUIRED  REQUIRED(有事务则加入,没有则创建)


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


SUPPORTS 支持事务,有没有都可以


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


MANDATORY(必须有事务,没有就抛异常)


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


REQUIRES_NEW(新事务,有事务就创建新事务)


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


NOT_SUPPORTED(不支持事务,有事务也是以非事务方式执行)


这个传播行为就是,不管咋地都传不到我身上,我就是一直以非事务方式执行。


如果当前存在事务,就当前事务挂起。


NEVER(不可能有事务,有事务就抛异常)


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


NESTED(嵌套事务,有事务就创建子事务)


如果当前方法存在事务,则创建一个子事务,等父事务提交以后,子事务再提交;如果当前没有事务,则新建事务。(子事务异常,父事务不一定回滚;但父事务异常,则子事务肯定回滚)


相关问题推荐

  • 回答 20

    100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...

  • 回答 5
    已采纳

    1、相同点(1)都是表现层框架,都是基于MVC设计模型(2)底层都离不开 Servlet API(3)处理请求的机制都是一个核心控制器2、不同点(1)SpringMVC的入口是Servlet,而Struts2的入口是Filter(2)SpringMVC是基于方法设计的,而Struts2是基于类(3)SpringMV...

  • 回答 22
    已采纳

    类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结...

  • 回答 23
    已采纳

    (1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...

  • 回答 12
    已采纳

    获取Map集合中所有的key可以通过map集合的keySet()方法获取例如:    Map map = new HashMap();    map.put(xx,xx); //存放数据    //.... 省略    Set set = map.keySet();    //可以通过迭代器进行测试    Iterator iter = set.iter...

  • 回答 4
    已采纳

    Java中有八种数据类型,基础数据类型分别是:byte,short,int,long,float,double,char,boolean,引用数据类型分别是:数组,类和接口。方法传参的时候我们有两种,一种是形式参数(定义方法时写的参数),一种是实际参数(调用方法时给的具体值)。首先...

  • 回答 15
    已采纳

    现在的架构很多,各种各样的,如高并发架构、异地多活架构、容器化架构、微服务架构、高可用架构、弹性化架构等,还有和这些架构相关的管理型的技术方法,如 DevOps、应用监控、自动化运维、SOA 服务治理、去 IOE 等等,还有很多。分布式架构其实就是分布式系...

  • 回答 10

    1、监控GC的状态使用各种JVM工具,查看当前日志,分析JVM参数的设置,分析堆内存快照和GC日志,根据实际的各区域的内存划分和GC的执行时间,判断是否需要进行优化2、分析结果、判断是否需要优化如果各项参数设置合理,系统没有超时的日志出现,GC频率也不高,...

  • 回答 9
    已采纳

    从两个方面对ElasticSearch和Solr进行对比,从关系型数据库中的导入速度和模糊查询的速度。单机对比1. Solr 发布了4.0-alpha,试了一下,发现需要自己修改schema,好处是它自带一个data importer。在自己的计算机上测试了一下,导入的性能大概是:14分钟导入 ...

  • 回答 10
    已采纳

    操作系统中有若干进程并发执行,它们不断申请、使用、释放系统资源,虽然系统的进 程协调、通信机构会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能 继续运行,否则就阻塞的情况。此时,若不借助外界因素,谁也不能释放资源,谁也不能解 ...

  • 回答 6

    MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以...

  • 回答 6

    学vue应该要先学习javascript 的基础知识和用法。

  • 回答 7

    synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象; 2. 修饰一个方法,被修饰的方法称为同步方法,其作用...

  • 回答 9

    是一个文件服务器,用来上传下载文件.它是一个分布式集群的.分2个角色调度和存储.上传时配置调度后上传.用的时候需要搭建.如果不会搭建想省事还可以选择阿里的oss .项目中应用还是比较多的因为一般项目都有文件上传和下载.选择目前就这2种方案.根据公司情况选...

  • 回答 8

    使用场景:常规key-value缓存应用。常规计数: 微博数, 粉丝数。实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。...

  • 回答 6

    一、装箱和拆箱原始类型转换为对象类型就是装箱,反之就是拆箱。原始类型byte,short,char,int,long,float,double,boolean对应的封装类为Byte,Shor,Character,Integer,Long,Float,Double,Boolean.二、源码解读自动装箱时编译器调用valueOf将原始类型值转换成对...

没有解决我的问题,去提问