Posted on 2006-12-06 08:45
兵臨城下 閱讀(425)
評論(0) 編輯 收藏 所屬分類:
Spring
TransactionTemplate 和TransactionInterceptor 都是將真正的事務處理代理給一個PlatformTransactionManager實例, 比如在Hibernate應用中它可以是一個HibernateTransactionManager (對于單獨一個的Hibernat SessionFactory, 實質上使用一個ThreadLocal的Session)或一個JtaTransactionManager (代理給容器的JTA子系統)。 你甚至可以使用自定義的PlatformTransactionManager的實現。 所以呢,如果你的應用需要分布式事務的時候, 將原來的Hibernate事務管理轉變為JTA之類的,只不過是改變配置文件的事情。 簡單地,將Hibernate transaction manager替換為Spring的JTA transaction實現。 事務的劃分和數據訪問代碼則不需要改變,因為他們使用的是通用的事務管理API。 對于橫跨多個Hibernate SessionFacotry的分布式事務, 只需簡單地將JtaTransactionManager 同多個LocalSessionFactoryBean 定義結合起來作為一個事務策略。 你的每一個DAO通過bean屬性得到各自的SessionFactory引用。 如果所有的底層JDBC datasource都是支持事務的容器, 那么只要一個業務對象使用了 JtaTransactionManager策略, 它就可以橫跨多個DAO和多個session factories來劃分事務,而不需要特殊的對待.
<beans>
<bean id="myDataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myds1</value>
</property>
</bean>
<bean id="myDataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myds2</value>
</property>
</bean>
<bean id="mySessionFactory1" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="dataSource">
<ref bean="myDataSource1"/>
</property>
</bean>
<bean id="mySessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>inventory.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
</props>
</property>
<property name="dataSource">
<ref bean="myDataSource2"/>
</property>
</bean>
<bean id="myTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/>
<bean id="myProductDao" class="product.ProductDaoImpl">
<property name="sessionFactory">
<ref bean="mySessionFactory1"/>
</property>
</bean>
<bean id="myInventoryDao" class="product.InventoryDaoImpl">
<property name="sessionFactory">
<ref bean="mySessionFactory2"/>
</property>
</bean>
<bean id="myProductServiceTarget" class="product.ProductServiceImpl">
<property name="productDao">
<ref bean="myProductDao"/>
</property>
<property name="inventoryDao">
<ref bean="myInventoryDao"/>
</property>
</bean>
<bean id="myProductService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="target">
<ref bean="myProductServiceTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
<prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop>
</props>
</property>
</bean>
</beans>
HibernateTransactionManager 和JtaTransactionManager 都使用了與容器無關的Hibernate事務管理器的lookup或JCA連接器(只要事務不是用EJB發起的), 從而考慮到在適當JVM級別上的cache處理。 而且HibernateTransactionManager 能夠為普通的JDBC訪問代碼輸出JDBC Connection。 這就可以使得混合的Hibernate/JDBC數據訪問可以不用JTA而在高層次上進行事務劃分, 只要它們使用的是同一個數據庫!