前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 事务传播行为

Spring 事务传播行为

作者头像
java404
发布2018-05-18 14:53:16
1.5K0
发布2018-05-18 14:53:16
举报
文章被收录于专栏:java 成神之路java 成神之路

如果对事务不了解的可以先看下,我的上一篇文章: 数据库事务详解

概述

一般SSH的项目都是使用三层架构即Controller、Services、DAO。

Spring 的事务一般都在Services定义,而Controller、DAO都不定义事务。

那么 Services 方法调用 Services 的方法,事务是怎么执行的?

有些人说不建议Service 调用Service,或者如果要Service 调用Service必须使用嵌套事务。真的是这样的吗?

带着疑问继续了解Spring事务传播行为

spring事务定义了7种传播行为,传播行为有什么作用?在什么情况下使用?

Spring 事务传播行为

Spring的TransactionDefinition类中定义了7中事务传播类型,代码如下:

我们先来假设一个场景

在 ServiceA 中方法 A() 调用 ServiceB 中方法 B()。

Spring 的事务传播行为就是解决方法之间的事务传播的。

基本方法调用场景如下:

  • 方法A有事务,方法B也有事务
  • 方法A有事务,方法B没有事务
  • 方法A没有事务,方法B有事务
  • 方法A没有事务,方法B也没有事务
1. PROPAGATION_REQUIRED

支持当前事务,如果当前没有事务,就新建一个事务。他也是Spring提供的默认事务传播行为,适合绝大数情况。

如果A方法有事务,那么B方法就使用A方法的事务。

如果A方法没有事务,那么B方法就创建一个新事物。

2. PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

如果A方法有事务,那么B方法就使用A方法的事务。

如果A方法没有事务,那么B方法就不使用事务的方式执行。

3. PROPAGATION_MANDATORY

支持当前事务,如果当前没有事务,就抛出异常。

如果A方法有事务,那么A方法就使用A方法事务。

如果A方法没有事务,那么就抛出异常。

该事务传播行为要求A方法必须以事务的方式运行

4. PROPAGATION_REQUIRES_NEW

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

如果A方法有事务,就把A方法的事务挂起,B方法新创建一个事务。

如果A方法没有事务,那么B方法就创建一个新事务。

5. PROPAGATION_NOT_SUPPORTED

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

如果A方法有事务,那么就把A方法的事务挂起,B方法以非事务的方式执行。

如果A方法没有事务,那么B也不使用事务执行。

6. PROPAGATION_NEVER

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

如果方法A有事务,那么就抛出异常。

如果方法A没有事务,那么B方法就以非事务的方式运行。

跟 3. PROPAGATION_MANDATORY 事务传播行为相反。

7. PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的。

如果A方法有事务,那么B方法就在A方法的事务中使用嵌套事务。

如果A方法没有事务,那么方法B就新创建一个事务。

嵌套事务

嵌套事务是使用数据库的SavePoint(事务保存点)。需要底层数据库的支持。

如果在Spring使用嵌套事务,需要满足一下3点。

  • 需要数据库支持。 可以使用以下代码来判断数据库是否支持。
Connection.getMetaData().supportsSavepoints();
  • JDK 1.4 才支持 java.sql.Savepoint 。所以JDK必须在1.4 及以上。
  • 还需要Spring中配置nestedTransactionAllowed=true。 我们要设置 transactionManager 的 nestedTransactionAllowed 属性为 true, 注意, 此属性默认为 false!!!
    <bean id="transactionManager"  
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
        <property name="nestedTransactionAllowed">  
            <value>true</value>  
        </property>  
    </bean> 

只读事务(Readonly Transaction)

Spring 为了忽略那些不需要事务的方法,比如读取数据,这样可以有效的提高一些性能。

事务超时 (Transaction Timeout)

为了解决事务执行时间太长,消耗太多资源的问题,可以设置一个超时时间。如果该事务支持超过设置的时间,就回滚该事务。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • Spring 事务传播行为
    • 1. PROPAGATION_REQUIRED
      • 2. PROPAGATION_SUPPORTS
        • 3. PROPAGATION_MANDATORY
          • 4. PROPAGATION_REQUIRES_NEW
            • 5. PROPAGATION_NOT_SUPPORTED
              • 6. PROPAGATION_NEVER
                • 7. PROPAGATION_NESTED
                • 嵌套事务
                • 只读事务(Readonly Transaction)
                • 事务超时 (Transaction Timeout)
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档