文档章节

Spring 传播行为(PROPAGATION)

年少爱追梦
 年少爱追梦
发布于 2016/04/16 15:25
字数 949
阅读 670
收藏 0

                                                                        Spring 传播行为

       Spring 中定义的七种传播行为,因为Spring将事务传播行为是交给事务管理器去实现的,所以使用之前第一步就是查看我们使用的事务管理器是否支持下面的七中传播行为:

      PROPAGATION_REQUIRED - -支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。  
      PROPAGATION_SUPPORTS - -支持当前事务,如果当前没有事务,就以非事务方式执行。  
      PROPAGATION_MANDATORY - -支持当前事务,如果当前没有事务,就抛出异常。  
      PROPAGATION_REQUIRES_NEW - -新建事务,如果当前存在事务,把当前事务挂起。  
      PROPAGATION_NOT_SUPPORTED - -以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。  
      PROPAGATION_NEVER - -以非事务方式执行,如果当前存在事务,则抛出异常。  

      我使用的是:org.springframework.jdbc.datasource.DataSourceTransactionManager 并不是完全是支持这七种传播行为的所以就有很多问题,使用其他的时候一定要关注一下,开始被坑哭了(DataSourceTransactionManager 不支持 PROPAGATION_NOT_SUPPORTED PROPAGATION_REQUIRES_NEW )。

      上面提了一下七种传播行为的含义,但是只看这个似乎有一点摸不着头脑,我个人认为传播行为的存在是为了解决各个事务方法之间调用可能出现的问题,(这里就涉及理念对实际可能出现的情况做的一种抽象)。      

       举一两个例子:传播行为“PROPAGATION_MANDATORY ”这个行为的意思就调用该方法的方法必须是一个事务方法(有点绕),很多时候我们对那些非常重要的数据进行删除,修改,增加的时候我们肯定希望他们的处于事务中,改到一半失败了,这个是超级可怕的事情。这个传播行为的价值就体现出来了,保证了调用该行为的方法都是事务方法。还有"PROPAGATION_NEVER ",不允许事务方法调用该方法,因为我们知道事务方法一般是有时间限制的,像一些超级耗时间的方法,我们给他加上这个传播行为,就可以提醒事务方法不要再使用这个了(不满足特殊情况哈)。

    上面只是提到一些理念对实际的抽象,传播行为之间最奇特的还是传播行为之间的组合可以解决很多实际上容易面临的问题。

    例如:下面举的例子都要关注事务边界哈:

    PROPAGATION_REQUIRED and  PROPAGATION_REQUIRED  传播行为的组合

@Transactional(propagation=Propagation.REQUIRED ,rollbackFor=AcceptPendingException.class)
	public void testRequiredAndRequired(){
	//事务开头
		insertInfo1();//包含在了testRequiredAndRequired里面
		insertInfo2();//包含在了testRequiredAndRequired里面
	//事务结束
	}
	@Transactional(propagation=Propagation.REQUIRED)
	public void insertInfo1(){
		ud.insert(10);
	//	throw new AcceptPendingException();
	}
	
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void insertInfo2(){
		ud.insert(11);
		throw new AbstractMethodError();
	}
	
	public static void main(String args[]) {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"com/springinaction/springidol/spring-tx.xml");
		UserService us = (UserService) ac.getBean("userService");
		us.testRequiredAndRequired();
	}

    发现传播行为:PROPAGATION_REQUIRED 事务边界内只要抛出异常,结果都会回滚。

    经过测试发现:PROPAGATION_REQUIRES_NEW  传播行为是在DataSourceTransactionManager 中不支持的,和PROPAGATION_REQUIRED 行为是相同的。

    PROPAGATION_REQUIRED  and Propagation.SUPPORTS 传播行为的组合

@Transactional(propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = AcceptPendingException.class)
	public void testRquiredAndSupported(){
	    //事务开始
		insertInfo1();
		insertInfo2();
	    //事务结束
	}

	@Transactional(propagation = Propagation.SUPPORTS, rollbackFor = AcceptPendingException.class)
	public void insertInfo1() {
		ud.insert(10);
		throw new  AcceptPendingException();
	}

//	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void insertInfo2() {
		ud.insertAccount(11);
	//	 throw new AbstractMethodError();
	}
	
	public static void main(String args[]) {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"com/springinaction/springidol/spring-tx.xml");
		UserService us = (UserService) ac.getBean("userService");
		us.insertInfo1();
	}

    当只有Propagation.SUPPORTS 转播行为的时候是没有事务边界的。当PROPAGATION_REQUIRED  下的SUPPORTS 的时候这个时候事务边界就是当前方法的事务边界。

    可见我们使用传播行为的时候主要就是关注事务的边界。就和可以很好的使用传播行为了。

    

    

     


© 著作权归作者所有

共有 人打赏支持
年少爱追梦
粉丝 31
博文 185
码字总数 118529
作品 0
杭州
程序员
私信 提问
Spring事务传播机制

概述 当我们调用一个基于Spring的Service接口方法(如UserService#addUser())时,它将运行于Spring管理的事务 环境中,Service接口方法可能会在内部调用其它的Service接口方法以共同完成一个...

rouway
2011/07/04
0
0
spring 事务管理 2(spring的事务方法镶嵌使用,事务边界和传播性)没完

许多人认为spring一个事务方法不应该调用另一个事务方法,否则将产生两个事务,其实是没有正确理解spring的事务传播性和边界 Spring 对事务控制的支持统一在 org.springframework.transactio...

jiangtao
2012/01/09
0
0
Spring的事务管理难点剖析(3):事务方法嵌套调用的迷茫

Spring事务传播机制回顾 Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务。结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷...

icheer
2012/07/17
0
0
Spring3事务管理——使用原始的TransactionProxyFactoryBean

Spring的早期版本用户必须通过TransactionProxyFactoryBean代理对需要事务管理的业务类进行代理,便于实施事务功能的增强。 让我们先看代码吧! 业务层代码: public interface UserScoreSe...

guanzhenxing
2014/03/28
0
0
Struts2+Spring+Hibernate3集成

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxdeng/article/details/52278238 1. 加入Struts2,Hibernate3.3,Spring3.3 和数据库驱动包 注意:当有包重复...

降龙十八腿
2016/08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

0029-如何实现CDH元数据库MySQL的主备

1.文档编写目的 MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的扩展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负...

Hadoop实操
14分钟前
2
0
阿里如何做到百万量级硬件故障自愈?

摘要: 随着阿里大数据产品业务的增长,服务器数量不断增多,IT运维压力也成比例增大。各种软、硬件故障而造成的业务中断,成为稳定性影响的重要因素之一。本文详细解读阿里如何实现硬件故障...

阿里云官方博客
16分钟前
4
0
配置resttemplate

<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder"factory-method="create"><property name="connectionManager"><bean class="org.apache.ht......

1713716445
18分钟前
0
0
Intersection of Two Linked Lists(leetcode160)

Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ......

woshixin
24分钟前
1
0
Jrebel最新激活破解方式(持续更新)

https://blog.csdn.net/xingbaozhen1210/article/details/81093041

glen_xu
25分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部