Spring总结之事务管理

传统的J2EE应用中,事务管理是跟EJB绑定在一起来的,那个时候大部分人使用EJBLocal SLSB仅仅是为了使用它的声明式事务管理罢了。随着技术不断向前发展,例如Spring的出现使得很多J2EE的核心理念不得不开始自省,在Spring的冲击之下完善自我变得更合理。于是JTA不在专属于EJB、与之相对的Local Transaction也在更适合的情况下得到重视。


这里简单总结一下Spring的事务管理,先回顾传统的J2EE中事务管理解决方案是全局容器管理事务,事务由应用服务器来协调,服务器登记所有参与事务的资源,在业务方法结束之后根据需要进行提交或者回滚。典型的例子就是EJB CMT,其优点是把繁琐的事务管理功能挪到了EJB部署描述符上,事务管理成了一个无需硬编码的横切面,当然它也有致命的缺点:只有EJB才能使用、必须使用重量级的全局事务管理、对于仅仅使用少量的事务就未免大材小用……


Spring的事务管理涉及初衷:(What we need?)

1、  可编程的事务管理和一致的异常处理机制。

2、  POJO上面实现的声明式事务、无需要绑定到重量级组件模型上

3、  可插拔的事务策略、以及让资源能够自由加入事务的手段

4、  为分布式容器而准备的JTA支持

5、  针对各种ORM框架集成而提供的数据源组件


下面正式介绍Spring的事务框架组成,主要核心为3个接口:TransactionDefinitionTransactionStatusPlatformTransactionManager。它们分别的职能如下:

TransactionDefinition

封装所有事务相关属性的设定。针对事务隔离性级别提供的属性有ISOLATION_DEFAULTISOLATION_READ_UNCOMMITTEDISOLATION_READ_COMMITTEDISOLATION_SERIALIZABLE。针对事务传播提供六个传播属性分别为PROPAGATION_REQUIREDPROPAGATION_SUPPORTSPROPAGATION_MANDATORYPROPAGATION_REQUIRES_NEWPROPAGATION_NOT_SUPPORTPROPAGATION_NESTED。用过EJB的会发觉这基本和EJB CMT保持一致。


TransactionStatus

它允许事务管理者控制事务的执行,只有3个接口方法:isNewTransaction()setRollbackOnly()isRollbackOnly()。其中setRollbackOnly将对当前事务进行回滚操作并将其终止。


PlatformTransactionManager

这是事务管理的策划者,它使用了前面两个接口来完成事务的创建和管理。它提供了getTransaction()commit()rollback()3个方法,针对一个给定的TransactionDefinition返回一个TransactionStatus对象,并且对这个状态对象触发提交或者回滚操作。如进行手工编程式的事务管理,基本就是操作这3个接口的实现类的编码在try/catch中间的代码块编写资源存取代码,事务运行结果就是Manager对象的提交或者回滚。

TransactionDefinition definition = new DefaultTransactionDefinition();
//set definition features here 
//… 
TransactionStatus status = transactionManager.getTransaction(definition);
try{
     //do some resource access 
     //or business logical use these resource 
}catch(BusinessException ex){
     transactionManager.rollback(status);
     throw ex;
}
transactionManager.commit(status);
//return some result 

编程式的事务管理要编写比较繁琐的代码,不是常用的方式。我们主要来看更加轻便高效的声明式事务管理(Declarative Transactions)。在Spring容器中声明式意味着我们要告知Spring某个Bean的某个方法需要事务管理,之后Spring会保证此方法被调用时候有事务贯穿其中。这种实现方式需要依赖AOP对方法调用进行拦截。Spring提供两种声明式的方式来创建一个事务管理代理(AOP的核心是动态代理)ProxyFactoryBeanTransactionProxyFactoryBean。看两个例子:

<beans>
    <bean id=”myTransactionManager” class=”org.springframework.transaction.jta.JtaTransactionManager”/>
     <bean id=”businessObjectTarget” class=”business.BusinessObject”/>
     <bean id=”transactionInterceptor” class=”org.springframework.transaction.interceptor.TransactionInterceptor”>
        <property name=”transactionManager”>
            <ref bean=”myTransactionManager”/>
        </property>
        <property name=”transactionAttributeSource”>
            <value>
               business.BusinessObject.method1=PROPAGATION_REQUIRED,-BusinessCheckedException
business.BusinessObject.method2=PROPAGATION_REQUIRED,+BusinessCheckedException
            </value>
         </property>
     </bean>  
     <!—隐式使用了CGLIB,集成代理对象以子类来代理-->
    <bean id=”myBusinessObject” class=”org.springframework.aop.framework.ProxyFactoryBean”>
        <property name=”interceptorNames”>
            <value>myTransactionInterceptor,businessObjectTarget</value>
        </property>
    </bean>
    <!—显示使用了JDK自带动态代理,必须指定代理接口,与上一个Bean二者选一-->
    <bean id=”myBusinessObject”  class=”org.springframework.aop.framework.ProxyFactoryBean”>
        <property name=”proxyInterfaces”>
            <value>business.BusinessInterface</value>
        </property>
        <property name=”interceptorNames”>
            <value>myTransactionInterceptor,businessObjectTarget</value>
        </property>
    </bean>
</beans>

再看另外一种使用TransactionProxyFactoryBean的方式配置的声明式事务管理:

<beans>
     <bean id=”myTransactionManager” class=”org.springframework.transaction.jta.JtaTransactionManager”/>
    <bean id=”businessObjectTarget” class=”business.BusinessObject”/>
    <bean id=”myBusinessObject” class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
        <property name=”transactionManager”>
            <refref=”myTransactionManager”/>
        </property>
        <property name=”target”>
            <ref bean=” businessObjectTarget”/>
        </property>
        <property name=”transactionAttributes”>
           <props>
             <prop key=”businessMethod1”>PROGATION_REQUIRE, -BusinessCheckedException</prop>
           </props>
        </property>
    </bean>
</beans>

此配置方法较之前一种比优点是把所有的配置项组织在一起,事务属性在代理类中统一定义。相当于集成了TransactionInterceptorProxyFactoryBean。同样代理也可以使用JDK自带或者CGLIB,通过指定proxyTargetClasstrue将强制使用CGLIB代理模式。

 

大体上Spring的事务管理就是这样,注意到所有的事务属性都通过key-value的形式在配置文件中的transactionAttributes或者transactionAttributeSource中指定,但目前更流行的一种方式的通过源码级别的元数据来设置事务属性。这一点我在之前写过的SpringOpenJPA的集成中已经举过例子。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值