Tuscany Home
 

新架构下的事务处理

From Tuscany中文社区

Jump to: navigation, search

新框架在事务模型方面,同样本着移植WebX的原则,目标是原有框架内容可以在OSGi环境中平稳运行,原有的事务效果没有下降。

目录

[编辑] WebX原有系统的事务处理过程

WebX利用Spring的AOP来控制一个VM下的对象级事务,通过Spring提供的BeanNameAutoProxyCreator来为指定的bean创建Proxy,并在指定的方法被调用的前后设置事务边界。

Image:Tx01.png

这张图是对springframework通过AOP处理事务的一个简要描述。

在描述事物AOP的时候,WebX使用了spring1.x的语法,如下:

  <bean id="matchAllTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager">
      <ref bean="transactionManager" />
    </property>
    <property name="transactionAttributes">
      <props>
        <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
        <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
    </property>
  </bean>
  <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
     <property name="interceptorNames">
       <list>
         <idref local="matchAllTxInterceptor" />
       </list>
     </property>
     <property name="beanNames">
       <list>
         <value>*Service</value>
       </list>
     </property>
  </bean>

[编辑] 新框架的事务模型

在新框架中,仍然只有那些服务类,即*Service类需要事务管理。这些对象分布在多个bundle中。 我们首先尝试了统一管理这些服务,即通过一个AOP管理所有的服务上的事务边界,但是效果很差,所以我们决定在每个bundle内对那些需要事务支持的bean声明事务。 新框架必须在那些将要“发布”为服务的bean上

这样,我们几乎不能接受spring 1.x的语法,即将上面的xml写入每个bundle,幸好,spring 2.x提供了更加简便的事务AOP声明方法,如下:

  <tx:annotation-driven transaction-manager="TM" />

其中的TM我们决定由一个PlatformTransactionManager服务提供,并在每个需要TM的bundle引用它。

当然,使用以上的xml需要在头部声明tx的namespace:

  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="...http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

但是这种声明方式导致了必须针对具体代码增加Annotation,也就是那些需要事务支持的method上(也可以是整个类上)使用@Transactional(org.springframework.transaction.annotation.Transactional)。注:该类位于spring-tx.jar内,但是该jar没有声明org.springframework.transaction.annotation为Export-Package,所以我们需要对这个jar的manifest.mf稍做修正。

需要添加@Transactional的类的方法,如下图所示:

Image:Tx02.png

新架构之所以采用这种事务声明方法,是为了简化每个bundle内的spring的描述代码量。

[编辑] HibernateTransactionManager与SessionFactory

在WebX中,使用了spring提供的HibernateTranactionManager,该类在spring的定义文件中需要依赖SessionFactory,如下图。 Image:Tx03.png

这个类图简要描述了HibernateTransactionManager与SessionFactory的关系。

新框架下,SessionFactory已经被“服务化”,每个DAO类都需要依赖该服务,而HibernateTransactionManager如果通过同一个bundle提供,则可以通过本地依赖来获取SessionFactory,我们也建议这样做,但是如果需要不同的bundle,则可以通过服务依赖。

[编辑] Spring AOP事务回滚条件

spring的aop tx在捕捉到来自被管理方法的RuntimeException或者Error的时候会回滚,但是Exception类型的异常则不会。

[编辑] Spring AOP事务嵌套

spring的aop tx支持事务的嵌套,但是事物边界只能位于一个method上,所以,如果需要将两个本管理方法并入一个事务,必须创建新的方法,通过它调用那两个方法,并在新的方法上设置@Transactional(或相当的方式),这种情况下,原来的两个方法上的事务声明将不再起作用(被嵌套入外层事务中)。

Personal tools