部分内容为摘抄,链接地址
http://blog.csdn.net/liushuijinger/article/details/17364413 (菜鸟学SSH(六)——Spring事务管理)
http://www.mamicode.com/info-detail-1248286.html(Spring事务管理(详解+实例))
http://www.blogjava.net/robbie/archive/2009/04/05/264003.html (Spring事务配置的五种方式)
http://www.cnblogs.com/rushoooooo/archive/2011/08/28/2155960.html (Spring声明式事务配置管理方法)
http://www.iteye.com/topic/1136891 (Spring 事务管理配置总结)
开发的时候我们会遇到一个问题,就是我们保存多表数据的时候,A表和B表存在关联关系,如果我们A表保存成功了,但是B表保存失败了,这样我们通过A表关联B表就会出现异常,因为A表中的关联字段在B表中无法查询。比如说:你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。
1:什么是事务
事务就是用来解决类似问题的。事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。 在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。
2:事务的特性
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
3:spring事务配置
Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。 Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。
4:spring事务具体配置
公共配置
注:使用的方法是通过配置数据库连接,注入hibernate数据库配置
<!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.yuanding.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<!-- 链接释放策略 on_close | after_transaction | after_statement | auto -->
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<!--prop key="hibernate.hbm2ddl.auto">update</prop-->
</props>
</property>
<property name="namingStrategy" >
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
</bean>
<!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
第一种,使用tx标签方式
<!-- 配置事务的传播特性 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.yuanding.biz..*.*(..))"/>
</aop:config>
execution(* com.yuanding.biz..*.*(..))
其中第一个*代表返回值,第二*代表biz下子包,第三个*代表方法名,“(..)”代表方法参数。
需要注意的地方:
(1) advice(建议)的命名:由于每个模块都会有自己的Advice,所以在命名上需要作出规范,初步的构想就是模块名+Advice(只是一种命名规范)。
(2) tx:attribute标签所配置的是作为事务的方法的命名类型。
如<tx:method name="save*" propagation="REQUIRED"/>
其中*为通配符,即代表以save为开头的所有方法,即表示符合此命名规则的方法作为一个事务。
propagation="REQUIRED"代表支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
(3) aop:pointcut标签配置参与事务的类,由于是在Service中进行数据库业务操作,配的应该是包含那些作为事务的方法的Service类。
首先应该特别注意的是id的命名,同样由于每个模块都有自己事务切面,所以我觉得初步的命名规则因为 all+模块名+ServiceMethod。而且每个模块之间不同之处还在于以下一句:
expression="execution(* com.test.testAda.test.model.service.*.*(..))"
其中第一个*代表返回值,第二*代表service下子包,第三个*代表方法名,“(..)”代表方法参数。
(4) aop:advisor标签就是把上面我们所配置的事务管理两部分属性整合起来作为整个事务管理。
第二种,使用代理方式
<!-- 第二种配置事务的方式 ,代理-->
<bean id="transactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
</props>
</property>
</bean>
<bean id="userDao" parent="transactionProxy">
<property name="target">
<!-- 用bean代替ref的方式-->
<bean class="com.dao.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</property>
</bean>
将transactionProxy的abstract属性设置为"true",然后将具体的Dao的parent属性设置为"transactionProxy",可以精简代码。
第三种,使用拦截器
<!-- 第三种配置事务的方式,拦截器 (不常用)-->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
</props>
</property>
</bean>
<bean id="proxyFactory" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>*Dao</value>
</list>
</property>
</bean>
5:Spring中常用事务类型:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
6:Spring 事务管理配置总结
Spring提供了如下所示的事务管理器
这些事务的父接口都是PlatformTransactionManager。Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用JTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。
Spring提供了许多内置事务管理器实现:
(1)DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
(2)
JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理;
<bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory" ref="persistenceManagerFactory"/>
</bean>
(3)
JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理;
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
……
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
(4)HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
(5)JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;
(6)OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
(7)WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
(8)WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。