2015第24周三Spring事务3

在一个典型的事务处理场景中,有以下几个参与者:

Resource Manager(RM)

ResourceManager简称RM,它负责存储并管理系统数据资源的状态,比如数据库服务器,JMS消息服务器等都是相应的Resource Manager。

Transaction Processing Monitor(TP Monitor)

Transaction Processing Monitor简称TPM或者TP Monitor,它的职责是在分布式事务场景中协调包含多个RM的事务处理。TP Monitor通常对应特定的软件中间件(Middleware), 随着软件开发技术的进步,TP Monitor的实现也由原来基于过程式的设计与实现转向面向对象的更趋模块化的设计和实现。J2EE规范[4]中的应用服务器(Application Server)通常担当的就是TP Monitor的角色。

Transaction Manager(TM)

Transaction Manager简称为TM,它可以认为是TP Monitor中的核心模块,直接负责多RM之间的事务处理的协调工作,并且提供事务界定(Transaction Demarcation)[5], 事务上下文传播(transaction context propagation)[6]等功能接口。

Application

以独立形式存在的或者运行于容器中的应用程序,可以认为是事务边界的触发点。

实际上,并非每一个事务的场景中都会出现以上提到的所有参与者,如果我们根据整个事务中牵扯的RM的多寡来区分事务类型的话,可以将事务分为两类,即全局事务(Global Transaction)和局部事务(Local Transaction),在这两类事务中,具体的事务参与者是不同的.

局部事务与全局事务的主要区分在于“事务”中牵扯多少RM,而不是“系统”中实际有多少RM,这是需要我们注意的地方。 即使你系统中存在多个数据库(即RM),只要你当前事务只更新一个数据库的数据,那当前事务就依然应该算作局部事务,而不是全局事务(虽然这种情况下,你也可以启用全局事务)。

实际上,针对单一事务资源的事务管理,你可以在局部事务中直接使用RM内置的事务支持来进行,你也可以引入TP Monitor在分布式事务场景中进行,通常情况下, 各TP Monitor在实现的时候会检测参与事务的RM数目,如果只有单一的RM参与,TP Monitor会做一定的优化,避免采用“两阶段提交”协议的负担, 但即使如此,针对单一事务资源参与的事务,直接采用局部事务中RM内置的事务支持,无论是从复杂度,还是从效率上来看,都要更胜一筹。

在Java的局部事务场景中,系统中事务管理的具体处理方式会随着所使用的数据访问技术的不同而各异,我们不是使用专用的事务API来管理事务, 而是通过当前使用的数据访问技术所提供的基于“connection” [7] 的API来管理事务。

Java平台上的分布式事务管理主要是通过Java Transaction API(JTA)或者Java Connector Architecture(JCA)提供支持的。

JTA是Sun提出的标准化分布式事务访问的Java接口规范。不过,JTA规范定义的只是一套Java接口定义,具体的实现留给了相应的提供商去实现,各JavaEE应用服务器需要提供对JTA的支持, 另外,除了可以使用绑定到各JavaEE应用服务器的JTA实现之外,Java平台上也存在几个独立的并且比较成熟的JTA实现产品,这包括:

使用JTA进行分布式事务管理通常有两种方式,直接使用JTA接口的编程事务管理以及基于应用服务器的声明性事务管理。

spring的事务框架将开发过程中事务管理相关的关注点进行适当的分离,并对这些关注点进行合理的抽象,最终打造了一套使用方便却功能强大的事务管理“利器”。 通过spring的事务框架,我们可以按照统一的编程模型来进行事务编程,却不用关心所使用的数据访问技术以及具体要访问什么类型的事务资源; 并且,spring的事务框架与spring提供的数据访问支持可以紧密结合,更是让你在事务管理与数据访问之间游刃有余,而最主要的,结合spring的AOP框架, spring的事务框架为我们带来了只有CMT才有的使用声明式事务管理的待遇,却无需绑定到任何的应用服务器上。

spring的事务抽象包括三个主要接口,即PlatformTransactionManager,TransactionDefinition以及TransactionStatus,三接口以org.springframework.transaction.PlatformTransactionManager为中心,org.springframework.transaction.PlatformTransactionManager负责界定事务边界,org.springframework.transaction.TransactionDefinition负责定义事务相关属性,包括隔离级别,传播行为等, org.springframework.transaction.PlatformTransactionManager将参照org.springframework.transaction.TransactionDefinition的属性定义来开启相关事务,事务开启之后到事务结束期间的事务状态由org.springframework.transaction.TransactionStatus负责, 我们也可以通过org.springframework.transaction.TransactionStatus对事务进行有限的控制。

TransactionDefinition针对事务的传播行为提供了以下几种选择,除了PROPAGATION_NESTED是spring特有的外,其他的传播行为的语义与CMT基本相同:

  • PROPAGATION_REQUIRED.  如果当前存在一个事务,则加入当前事务;如果不存在任何事务,则创建一个新的事务。总之,要至少保证在一个事务中运行。PROPAGATION_REQUIRED通常作为默认的事务传播行为。
  • PROPAGATION_SUPPORTS.  如果当前存在一个事务,则加入当前事务;如果当前不存在事务,则直接执行。 对于一些查询方法来说,PROPAGATION_SUPPORTS通常是比较合适的传播行为选择。 如果当前方法直接执行,那么不需要事务的支持;如果当前方法被其他方法调用,而其他方法启动了一个事务的时候,使用PROPAGATION_SUPPORTS可以保证当前方法能够加入当前事务并洞察当前事务对数据资源所做的更新。 比如说,A.service()会首先更新数据库,然后调用B.service()进行查询,那么,B.service()如果是PROPAGATION_SUPPORTS的传播行为, 就可以读取A.service()之前所做的最新更新结果,而如果使用稍后所提到的PROPAGATION_NOT_SUPPORTED,则B.service()将无法读取最新的更新结果,因为A.service()的事务在这个时候还没有提交(除非隔离级别是read uncommitted):
  • PROPAGATION_MANDATORY.  PROPAGATION_MANDATORY强制要求当前存在一个事务,如果不存在,则抛出异常。 如果某个方法需要事务支持,但自身又不管理事务提交或者回滚的时候,比较适合使用PROPAGATION_MANDATORY。 你可以参照《JAVA TRANSACTION DESIGN STRATEGIES》一书中对REQUIRED和MANDATORY两种传播行为的比较来更深入的了解PROPAGATION_MANDATORY的可能应用场景。
  • PROPAGATION_REQUIRES_NEW.  不管当前是否存在事务,都会创建新的事务。如果当前存在事务的话,会将当前的事务挂起(suspend)。 如果某个业务对象所做的事情不想影响到外层事务的话,PROPAGATION_REQUIRES_NEW应该是合适的选择,比如,假设当前的业务方法需要向数据库中更新某些日志信息, 但即使这些日志信息更新失败,我们也不想因为该业务方法的事务回滚而影响到外层事务的成功提交,因为这种情况下,当前业务方法的事务成功与否对外层事务来说是无关紧要的。
  • PROPAGATION_NOT_SUPPORTED.  不支持当前事务,而是在没有事务的情况下执行。如果当前存在事务的话,当前事务原则上将被挂起(suspend),但要依赖于对应的PlatformTransactionManager实现类是否支持事务的挂起(suspend),更多情况请参照TransactionDefinition的javadoc文档。 PROPAGATION_NOT_SUPPORTED与PROPAGATION_SUPPORTS之间的区别,可以参照PROPAGATION_SUPPORTS部分的实例内容。
  • PROPAGATION_NEVER.  永远不需要当前存在事务,如果存在当前事务,则抛出异常。
  • PROPAGATION_NESTED.  如果存在当前事务,则在当前事务的一个嵌套事务中执行,否则与PROPAGATION_REQUIRED的行为类似,即创建新的事务,在新创建的事务中执行。 PROPAGATION_NESTED粗看起来好像与PROPAGATION_REQUIRES_NEW的行为类似,实际上二者是有差别的。 PROPAGATION_REQUIRES_NEW创建的新事务与外层事务属于同一个“档次”,即二者的地位是相同的,当新创建的事务运行的时候,外层事务将被暂时挂起(suspend); 而PROPAGATION_NESTED创建的嵌套事务则不然,它是寄生于当前外层事务的,它的地位比当前外层事务的地位要小一号,当内部嵌套事务运行的时候,外层事务也是出于active状态:

    也就是说,PROPAGATION_REQUIRES_NEW新创建的事务虽然是在当前外层事务内执行,但新创建的事务是独立于当前外层事务而存在的,二者拥有各自独立的状态而互不干扰; 而PROPAGATION_NESTED创建的事务属于当前外层事务的内部子事务(sub-transaction),内部子事务的处理内容属于当前外层事务的一部分,而不能独立于外层事务而存在,并且与外层事务共有事务状态,我想这也就是为什么称其为内部嵌套事务的原因。

    PROPAGATION_NESTED可能的应用场景在于,你可以将一个大的事务划分为多个小的事务来处理,并且外层事务可以根据各个内部嵌套事务的执行结果来选择不同的执行流程。 比如,某个业务对象的业务方法A.service()可能调用其他业务方法B.service()向数据库中插入一批业务数据,但当插入数据的业务方法出现错误的时候(比如主键冲突),我们可以在当前事务中捕捉前一个方法抛出的异常,然后选择另一个更新数据的业务方法C.service()来执行, 这个时候,我们就可以把B.service()和C.serivce()方法的传播行为指定为PROPAGATION_NESTED

    不过,并非所有的PlatformTransactionManager实现都支持PROPAGATION_NESTED类型的传播行为,现在只有org.springframework.jdbc.datasource.DataSourceTransactionManager在使用JDBC3.0数据库驱动的情况下才支持(当然,数据库和相应的驱动程序也需要提供支持),另外, 某些JtaTransactionManager也可能提供支持,但JTA规范并没有要求提供对嵌套事务的支持。

    PlatformTransactionManager是spring事务抽象框架的核心组件,关于它的定义以及作用我们之前已经提过了,所以,这部分我们不妨更多的关注一下PlatformTransactionManager整个的层次体系以及针对不同数据访问技术的实现类。

    PlatformTransactionManager整个的抽象体系基于Strategy模式,由PlatformTransactionManager对事务界定进行统一抽象,而具体的界定策略的实现则交由具体的实现类。 下面我们先来看一下有哪些实现类可供我们使用.

    PlatformTransactionManager的实现类可以划分到面向局部事务和面向全局事务两个分支:

    • 面向局部事务的PlatformTransactionManager实现类.  spring为各种数据访问技术提供了现成的PlatformTransactionManager实现支持,以下列表给出了各种数据访问技术与它们对应的实现类的关系:

      数据访问技术 PlatformTransactionManager实现类
      JDBC/iBatis DataSourceTransactionManager
      Hibernate HibernateTransactionManager
      JDO JdoTransactionManager
      JPA(Java Persistence API) JpaTransactionManager
      TopLink TopLinkTransactionManager
      JMS JmsTransactionManager
      JCA Local Transaction CciLocalTransactionManager

      在这些实现类当中,CciLocalTransactionManager可能是比较少见的实现,CCI的意思是Common Client Interface, CciLocalTransactionManager主要是面向JCA的局部事务(Local Transaction),本书不打算对JCA的集成做过多的阐述,读者如果在实际项目中需要使用到JCA进行EIS(Enterprise Information System)系统集成,你可以从spring的参考文档获得使用spring提供的JCA集成支持的足够信息。

      有了这些实现类,我们在使用spring的事务抽象框架进行事务管理的时候,只需要根据当前使用的数据访问技术选择对应的PlatformTransactionManager实现类即可。

    摘自:http://www.cnblogs.com/superjt/archive/2013/05/20/3088847.html

时间: 2024-10-05 22:16:16

2015第24周三Spring事务3的相关文章

2015第24周二Spring事务2

今天继续深入学习SPring事务,发现网上很多文章都是很相似的转载没多少价值,就觉得更有必要把这个主题深入下去,先是摘录那些对自己有用的观点,后期再结合源码进行全面的整理. Spring提供了许多内置事务管理器实现,常用的有以下几种: DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架.iBATIS

2015第24周一Spring事务

1. Spring事务管理简介 (1)Spring为多种不同类型的事务管理机制提供统一编程模型,这些事务管理模型包括JTA.JDBC.Hibernate.JPA和JDO. (2)Spring支持声明式事务管理(使用XML文档配置(或者Annotation)结合AOP实现的事务管理). (3)为代码嵌入式(programmatic)的事务管理提供API接口,与复杂的JTA接口相比要简单的多. (4)能够与Spring的数据抽象访问完美结合. 2. Spring事务管理的优点 一般认为,JavaEE

2015第24周四Spring事务4

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分.     DataSource.TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager.    

2015第30周三Spring常用工具类

文件资源操作 文件资源的操作是应用程序中常见的功能,如当上传一个文件后将其保存在特定目录下,从指定地址加载一个配置文件等等.我们一般使用 JDK 的 I/O 处理类完成这些操作,但对于一般的应用程序来说,JDK 的这些操作类所提供的方法过于底层,直接使用它们进行文件操作不但程序编写复杂而且容易产生错误.相比于 JDK 的 File,Spring 的 Resource 接口(资源概念的描述接口)抽象层面更高且涵盖面更广,Spring 提供了许多方便易用的资源操作工具类,它们大大降低资源操作的复杂度

2015第24周五Spring的AOP

AOP(面向方面编程:Aspect Oriented Programing)和IoC一样是Spring容器的内核,声明式事务的功能在此基础上开花结果.但AOP的应用场合是受限的,它一般只适合于那些具有横切逻辑的应用场合:如性能监测.访问控制.事务管理以及日志记录. AOP相关重要术语: 连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化前.类初始化后.类某个方法调用前.调用后.方法抛出异常后.一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就称为“连接点”.

Spring 事务 readOnly 到底是怎么回事?

Spring的事务经常会有这样的配置: 1 <tx:method name="search*" read-only="true" /> 或者这样的注记: 1 @Transactional(readOnly = true) 正好我正在做的项目中这样配置了,而且偶然发现配置了不生效,本着“不弄明白对不起祖国对不起人民”的精神,参考了不少帖子和文档,总结了网上形形色色的答案,稍有收获,规整如下,不正确请指出. 1 readonly并不是所有数据库都支持的,不同

Spring 事务管理高级应用难点剖析--转

第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN&en=utf&hpp=20&dws=cndw&lo=zh 概述 Spring 最成功,最吸引人的地方莫过于轻量级的声明式事务管理,仅此一点,它就宣告了重量级 EJB 容器的覆灭.Spring 声明式事务管理将开发者从繁复的事务管理代码中解脱出来,专注于业务逻辑的开发上,这是一件

Spring事务Transaction配置的五种注入方式详解

Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ??? 总结如下: ??? Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. ???DataSou

[Spring框架]Spring 事务管理基础入门总结.

前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一, 什么是事务 事务是逻辑上一组操作,这组操作要么全都成功,要么全都失败. 事务的属性: ACID原子性(Atomicity): 事务作为一个整体被执行,包含在其中的对数据的操作要么全部被执行,要么都不执行.一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态.