Spring事务管理及与mybatis整合的事务管理_第1页
Spring事务管理及与mybatis整合的事务管理_第2页
Spring事务管理及与mybatis整合的事务管理_第3页
Spring事务管理及与mybatis整合的事务管理_第4页
Spring事务管理及与mybatis整合的事务管理_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据访问事务处理inSpring+Mybatis3.0事务---保证了用户的每一次操作都是可靠的,即使出现了异常的访问,也不至于破坏后台数据的完整性;Java事务简介事务必须符合ISO/IEC所定制的ACID原则A(atomicity):原子性在事务执行的过程中,任何的失败就将导致事务的任何修改失效,C(consistency):—致性事务回滚时,事务所执行的内容必须恢复到初始状态,即事务执行前的状态I(isolation):隔离性事务执行过程中对数据的修改,在提交之前的数据对其他事务不可见D(durability):持久性已经提交的数据在事务执行失败时,数据的状态都是正确的.事务分类:全局事务(分布式事务):由应用服务器来管理(如JTA),同时可以用于多个事务性的资源;本地事务本地事务和资源相关,主要通过JDBC来实现在实际应用中,存在一种容器管理事务,容器事务主要是由javaEE应用服务器提供,容器事务大多给予JTA完成,事实上这是在容器中覆盖了JDBC和JTA事务.事务特性分析(usespring)TransactionDefinition接口来定义事务属性。Code:publicinterfaceTransactionDefinition{intgetlsolationLevel();intgetPropagationBehavior();intgetTimeout();booleanisReadOnly();}事务机制a)事务隔离级别隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition接口中定义了五个表示隔离级别的常量:TransactionDefinition.ISOLATION_DEFAULT(默认值):表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。TransactionDefinition.lSOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。TransactionDefinition.lSOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。隔离级别定义了事务与事务之间的隔离程度。隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。ANSI/ISOSQL92标准定义了一些数据库操作的隔离级别:未提交读(readuncommitted)提交读(readcommitted)重复读(repeatableread)序列化(serializable)通过一些现象,可以反映出隔离级别的效果。这些现象有:更新丢失(lostupdate):当系统允许两个事务同时更新同一数据是,发生更新丢失。脏读(dirtyread):当一个事务读取另一个事务尚未提交的修改时,产生脏读。非重复读(nonrepeatableread):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。(Atransactionrereadsdataithaspreviouslyreadandfindsthatanothercommittedtransactionhasmodifiedordeletedthedata.)幻读(phantomread):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。(Atransactionreexecutesaqueryreturningasetofrowsthatsatisfiesasearchconditionandfindsthatanothercommittedtransactionhasinsertedadditionalrowsthatsatisfythecondition.)隔离级别影响部分:isoXatiQJiXevelDirtyReadHojiRepeatableReadPhantomReaduiicuiEinilt.r.eclPossPossibisP□曰曰ibReadcoinmittedNotpossitolePossitolePossiloleRep已at.;5i}jlereadMcit.possilzi丄已Not-possilzi丄已Pussiljl已Seuializ=zi}zileMotpossibleNot-possibleI'-Futpussibleb)事务传播行为所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。此处涉及到【嵌套事务】内部事务依赖于外部事务外部事务的提交和回滚直接影响到内部事务(内部事务不是独立的)c)事务超时指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在TransactionDefinition中以int的值来表示超时时间,其单位是秒。事务的只读属性(readonly)对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、JMS资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在TransactionDefinition中以boolean类型来表示该事务是否只读。事务的回滚规则通常情况下,如果在事务中抛出了未检查异常(继承自RuntimeException的异常),则默认将回滚事务。如果没有抛出任何异常,或者抛出了已检查异常,则仍然提交事务。这通常也是大多数开发者希望的处理方式,也是EJB中的默认处理方式。但是,我们可以根据需要人为控制事务在抛出某些未检查异常时任然提交事务,或者在抛出某些已检查异常时回滚事务。TransactionDefinition、PlatformTransactionManager、TransactionStatus事务管理,其实就是“按照给定的事务规则来执行提交或者回滚操作”。“给定的事务规则”就是用TransactionDefinition表示的,“按照„„来执行提交或者回滚操作”便是用PlatformTransactionManager来表示,而TransactionStatus用于表示一个运行着的事务的状态。PlatformTransactionManager用于执行具体的事务操作。PublicinterfacePlatformTransactionManager{TransactionStatusgetTransaction(TransactionDefinitiondefinition)throwsTransactionException;voidcommit(TransactionStatusstatus)throwsTransactionException;voidrollback(TransactionStatusstatus)throwsTransactionException;}根据底层所使用的不同的持久化API或框架,PlatformTransactionManager的主要实现类大致如下:DataSourceTransactionManager:适用于使用JDBC和iBatis进行数据持久化操作的情况。HibernateTransactionManager:适用于使用Hibernate进行数据持久化操作的情况。JpaTransactionManager:适用于使用JPA进行数据持久化操作的情况。另外还有JtaTransactionManager、JdoTransactionManager、JmsTransactionManager等等。如果我们使用JTA进行事务管理,我们可以通过JNDI和Spring的JtaTransactionManager来获取一个容器管理的DataSource。JtaTransactionManager不需要知道DataSource和其他特定的资源,因为它将使用容器提供的全局事务管理。而对于其他事务管理器,比如DataSourceTransactionManager,在定义时需要提供底层的数据源作为其属性,也就是DataSource。与HibernateTransactionManager对应的是SessionFactory,与JpaTransactionManager对应的是EntityManagerFactory等等。TransactionStatusPlatformTransactionManager.getTransactio方法返回一个Transactionstatus对象。返回的Transactionstatus对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务)。TransactionStatus接口提供了一个简单的控制事务执行和查询事务状态的方法。publicinterfaceTransactionstatus{booleanisNewTransaction();voidsetRollbackOnly();booleanisRollbackOnly();}Spring的编程式事务管理在spring出现以前,编程式事务管理对基于POJO的应用来说是唯一选择。用过Hibernate的人都知道,需要在代码中显式调用beginTransaction()、commit()、rollback。等事务管理相关的方法,这就是编程式事务管理。通过Spring提供的事务管理API,我们可以在代码中灵活控制事务的执行。在底层,Spring仍然将事务操作委托给底层的持久化框架来执行。声明式事务管理(方便代码维护,无污染,无重复代码,但是粒度控制不够)spring的声明式事务管理在底层是建立在AOP的基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过等价的基于标注的方式),便可以将事务规则应用到业务逻辑中。因为事务管理本身就是一个典型的横切逻辑,正是AOP的用武之地。通常情况下,笔者强烈建议在开发中使用声明式事务,不仅因为其简单,更主要是因为这样使得纯业务代码不被污染,极大方便后期的代码维护。基于transactionIntercepter<beans><beanid="transactionInterceptor"class="erceptor.TransactionInterceptor"><propertyname="transactionManager"ref="transactionManager"/><propertyname="transactionAttributes"><props><propkey="transfer">PROPAGATION_REQUIRED,-XXException,+xxxException</prop></props></property></bean><beanid="serviceTarget"class="com.ncs.test.TestService"><propertyname="testDao"ref="testDao"/></bean><beanid="service"class="org.springframework.aop.framework.ProxyFactoryBean"><propertyname="target"ref="serviceTarget"/><propertyname="interceptorNames"><list><idrefbean="transactionInterceptor"/></list></property></bean></beans>我们配置了一个Transactioninterceptor来定义相关的事务规则,他有两个主要的属性:一个是transactionManager,用来指定一个事务管理器,并将具体事务相关的操作委托给它;另一个是Properties类型的transactionAttributes属性,它主要用来定义事务规则,该属性的每一个键值对中,键指定的是方法名,方法名可以使用通配符,而值就表示相应方法的所应用的事务属性。指定事务属性的取值有较复杂的规则:格式:传播行为[,隔离级别][,只读属性][,超时属性][不影响提交的异常][,导致回滚的异常]传播行为是唯一必须设置的属性,其他都可以忽略,Spring为我们提供了合理的默认值。传播行为的取值必须以“PROPAGATION—"开头,具体包括:PROPAGATION_MANDATORY、PROPAGATION_NESTED、PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED、PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_SUPPORTS,共七种取值。隔离级别的取值必须以“ISOLATION—”开头,具体包括:ISOLATION_DEFAULT、ISOLATION_READ_COMMITTED、ISOLATION_READ_UNCOMMITTED、ISOLATION_REPEATABLE_READ、ISOLATION_SERIALIZABLE,共五种取值。如果事务是只读的,那么我们可以指定只读属性,使用“readOnly”指定。否则我们不需要设置该属性。超时属性的取值必须以“TIMEOUT_”开头,后面跟一个int类型的值,表示超时时间,单儷秒。不影响提交的异常是指,即使事务中抛出了这些类型的异常,事务任然正常提交。必须在每一个异常的名字前面加上“+”。异常的名字可以是类名的一部分。比如“+RuntimeException”、“+tion”等等。导致回滚的异常是指,当事务中抛出这些类型的异常时,事务将回滚。必须在每一个异常的名字前面加上“-”。异常的名字可以是类名的全部或者部分,比如“-RuntimeException”、“-tion”等等。例子:<propertyname="*Service">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20,+AbcException,+DefException,-HijException</property>基于TransactionProxyFactoryBean的声明式事务管理前面的声明式事务虽然好,但是配置文件太多。我们必须针对每一个目标对象配置一个ProxyFactoryBean;另外,虽然可以通过父子Bean的方式来复用TransactionInterceptor的配置,但是实际的复用几率也不高;这样,加上目标对象本身,每一个业务类可能需要对应三(<bean/>配置,随着业务类的增多,配置文件将会变得越来越庞大,管理配置文件又成了问题。为了缓解这个问题,Spring为我们提供了TransactionProxyFactoryBean,用于将TransactionInterceptor和ProxyFactoryBean的配置合二为一。<beans><beanid="testServiceTarget"class="org.test.core.Test"><propertyname="testDao"ref="testDao"/></bean><beanid="testService"class="erceptor.TransactionProxyFactoryBean"><propertyname="target"ref="testServiceTarget"/><propertyname="transactionManager"ref="transactionManager"/><propertyname="transactionAttributes"><props><propkey="transfer">PROPAGATION_REQUIRED</prop></props></property></bean></beans>基于Vfx>命名空间的声明式事务管理前面两种声明式事务配置方式奠定了Spring声明式事务管理的基石。在此基础上,Spring2.x引入j<tx>命名空间,结合使用<aop>命名空间,带给开发人员配置声明式事务的全新体验,配置变得更加简单和灵活。另外,得益^aop>命名空间的切点表达式支持,声明式事务也变得更加强大。XML:<beans><beanid="testService"class="com.ncs.testtestService"><propertyname="testDao"ref="testDao"/></bean><tx:adviceid="testAdvice"transaction-manager="transactionManager"><tx:attributes><tx:methodname="transfer"propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><aop:pointcutid="testPointcut"expression="execution(**.transfer(..))"/><aop:advisoradvice-ref="testAdvice"pointcut-ref="testPointcut"/></aop:config></beans>简化:<beans><beanid="testService"class="com.ncs.testtestService"><propertyname="testDao"ref="testDao"/></bean><tx:adviceid="testAdvice"transaction-manager="transactionManager"><aop:config><aop:pointcutid="testPointcut"expression="execution(**.transfer(..))"/><aop:advisoradvice-ref="testAdvice"pointcut-ref="testPointcut"/></aop:config></beans>基于@Transactional的声明式事务管理事务配置:<beanname="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论