新架构下的事务处理
From Tuscany中文社区
新框架在事务模型方面,同样本着移植WebX的原则,目标是原有框架内容可以在OSGi环境中平稳运行,原有的事务效果没有下降。
目录 |
[编辑] WebX原有系统的事务处理过程
WebX利用Spring的AOP来控制一个VM下的对象级事务,通过Spring提供的BeanNameAutoProxyCreator来为指定的bean创建Proxy,并在指定的方法被调用的前后设置事务边界。
这张图是对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的类的方法,如下图所示:
新架构之所以采用这种事务声明方法,是为了简化每个bundle内的spring的描述代码量。
[编辑] HibernateTransactionManager与SessionFactory
在WebX中,使用了spring提供的HibernateTranactionManager,该类在spring的定义文件中需要依赖SessionFactory,如下图。
这个类图简要描述了HibernateTransactionManager与SessionFactory的关系。
新框架下,SessionFactory已经被“服务化”,每个DAO类都需要依赖该服务,而HibernateTransactionManager如果通过同一个bundle提供,则可以通过本地依赖来获取SessionFactory,我们也建议这样做,但是如果需要不同的bundle,则可以通过服务依赖。
[编辑] Spring AOP事务回滚条件
spring的aop tx在捕捉到来自被管理方法的RuntimeException或者Error的时候会回滚,但是Exception类型的异常则不会。
[编辑] Spring AOP事务嵌套
spring的aop tx支持事务的嵌套,但是事物边界只能位于一个method上,所以,如果需要将两个本管理方法并入一个事务,必须创建新的方法,通过它调用那两个方法,并在新的方法上设置@Transactional(或相当的方式),这种情况下,原来的两个方法上的事务声明将不再起作用(被嵌套入外层事务中)。



