从J2EE应用程序内部连接到单个的数据库并不是什么难事。但是,如果要装配或者集成企业级的组件,情况就复杂了。一个组件可以有一个或多个支持它的数据库,因此,当装配两个或更多的组件时,我们希望能够保持在跨组件的多个数据库中进行的操作的原子性。J2EE服务器为这些组件提供了一个容器来保证事务原子性和跨组件独立性。如果使用的不是J2EE服务器,则可以利用Spring来帮助我们。Spring基于Inversion of Control(控制反转)模式(也称为依赖注入),它不仅可以连接组件服务,还可以连接关联的事务上下文 。
使用Spring进行事务管理
我们将看到一个轻量级的事务基础架构,它实际上可以管理组件级的事务装配。Spring是其中的一个解决方案。它的优点在于,我们不会被捆绑到J2EE容器服务(如JNDI DataSource)上。最棒的一点是,如果我们想把这个轻量级事务基础架构关联到一个已可用的J2EE容器基础架构,将不会有任何问题。看起来我们可以利用两者的优点。
另一方面,Spring这个轻量级事务基础架构使用了一个面向方面编程(Aspect-Oriented Programming,AOP)框架。Spring AOP框架使用了一个支持AOP的Spring bean工厂。在特定于Spring的配置文件applicationContext.xml中,通过在组件服务级指定事务特性来划分事务。
<beans>
<!-- other code goes here... -->
<bean id="orderListManager"
class="org.springframework.transaction
.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager1"/>
</property>
<property name="target">
<ref local="orderListManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="getAllOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="getOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="createOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="addLineItem">
PROPAGATION_REQUIRED,
-com.example.exception.FacadeException
</prop>
<prop key="getAllLineItems">
PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="queryNumberOfLineItems">
PROPAGATION_REQUIRED,readOnly
</prop>
</props>
</property>
</bean>
</beans>
一旦我们在服务级指定了事务属性,org.springframework.transaction.PlatformTransactionManager接口的一个特定实现就会截获并解释它们。该接口如下:
public interface PlatformTransactionManager...{
TransactionStatus getTransaction
(TransactionDefinition definition);
void commit(TransactionStatus status);
void rollback(TransactionStatus status);
}
TransactionStatus getTransaction
(TransactionDefinition definition);
void commit(TransactionStatus status);
void rollback(TransactionStatus status);
}