文档章节

Spring 传播行为(PROPAGATION)

年少爱追梦
 年少爱追梦
发布于 2016/04/16 15:25
字数 949
阅读 666
收藏 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
博文 184
码字总数 117969
作品 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

没有更多内容

加载失败,请刷新页面

加载更多

如何通过 J2Cache 实现分布式 session 存储

做 Java Web 开发的人多数都会需要使用到 session (会话),我们使用 session 来保存一些需要在两个不同的请求之间共享数据。一般 Java 的 Web 容器像 Tomcat、Resin、Jetty 等等,它们会在...

红薯
今天
1
0
C++ std::thread

C++11提供了std::thread类来表示一个多线程对象。 1,首先介绍一下std::this_thread命名空间: (1)std::this_thread::get_id():返回当前线程id (2)std::this_thread::yield():用户接口...

yepanl
今天
2
0
Nignx缓存文件与动态文件自动均衡的配置

下面这段nginx的配置脚本的作用是,自动判断是否存在缓存文件,如果有优先输出缓存文件,不经过php,如果没有,则回到php去处理,同时生成缓存文件。 PHP框架是ThinkPHP,最后一个rewrite有关...

swingcoder
今天
1
0
20180920 usermod命令与用户密码管理

命令 usermod usermod 命令的选项和 useradd 差不多。 一个用户可以属于多个组,但是gid只有一个;除了gid,其他的组(groups)叫做扩展组。 usermod -u 1010 username # 更改用户idusermod ...

野雪球
今天
1
0
Java网络编程基础

1. 简单了解网络通信协议TCP/IP网络模型相关名词 应用层(HTTP,FTP,DNS等) 传输层(TCP,UDP) 网络层(IP,ICMP等) 链路层(驱动程序,接口等) 链路层:用于定义物理传输通道,通常是对...

江左煤郎
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部