??xml version="1.0" encoding="utf-8" standalone="yes"?>
TransactionTemplate ?tt class="classname">TransactionInterceptor 都是真正的事务处理代理l一?tt class="classname">PlatformTransactionManager实例Q?比如在Hibernate应用中它可以是一?tt class="classname">HibernateTransactionManager Q对于单独一个的Hibernat SessionFactoryQ?实质上用一个ThreadLocal的SessionQ或一?tt class="classname">JtaTransactionManager Q代理给容器的JTA子系l)?你甚臛_以用自定义?tt class="classname">PlatformTransactionManager的实现?所以呢Q如果你的应用需要分布式事务的时候, 原来的Hibernate事务理转变为JTA之类的,只不q是改变配置文g的事情?单地Q将Hibernate transaction manager替换为Spring的JTA transaction实现?事务的划分和数据讉K代码则不需要改变,因ؓ他们使用的是通用的事务管理API?对于横跨多个Hibernate SessionFacotry的分布式事务Q?只需单地?tt class="classname">JtaTransactionManager 同多?tt class="classname">LocalSessionFactoryBean 定义l合h作ؓ一个事务策略?你的每一个DAO通过bean属性得到各自的SessionFactory引用?如果所有的底层JDBC datasource都是支持事务的容器, 那么只要一个业务对象用了 JtaTransactionManager{略Q?它就可以横跨多个DAO和多个session factories来划分事务,而不需要特D的对待.
HibernateTransactionManager ?tt class="classname">JtaTransactionManager 都用了与容器无关的Hibernate事务理器的lookup或JCAq接器(只要事务不是用EJB发v的)Q?从而考虑到在适当JVMU别上的cache处理?而且HibernateTransactionManager 能够为普通的JDBC讉K代码输出JDBC Connection?q就可以使得混合的Hibernate/JDBC数据讉K可以不用JTA而在高层ơ上q行事务划分Q?只要它们使用的是同一个数据库! 我们可以使用Spring的AOP TransactionInterceptor来替换事务划分的手工代码Q?q需要在application context中定义interceptor?q个Ҏ使得你可以把业务对象从每个业务方法中重复的事务划分代码中解放出来?此外Q像传播行ؓ和隔ȝ别等事务概念能够在配|文件中改变Q而不会媄响业务对象的实现?<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>
]]><beans>
...
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="myTransactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="transactionAttributeSource">
<value>
product.ProductService.increasePrice*=PROPAGATION_REQUIRED
product.ProductService.someOtherBusinessMethod=PROPAGATION_MANDATORY
</value>
</property>
</bean>
<bean id="myProductServiceTarget" class="product.ProductServiceImpl">
<property name="productDao">
<ref bean="myProductDao"/>
</property>
</bean>
<bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>product.ProductService</value>
</property>
<property name="interceptorNames">
<list>
<value>myTransactionInterceptor</value>
<value>myProductServiceTarget</value>
</list>
</property>
</bean>
</beans>
public class ProductServiceImpl implements ProductService {
private ProductDao productDao;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
public void increasePriceOfAllProductsInCategory(final String category) {
List productsToChange = this.productDAO.loadProductsByCategory(category);
...
}
...
}
一个简便可选的创徏声明式事务的Ҏ是:TransactionProxyFactoryBeanQ?特别是在没有其他AOP interceptor牉|到的情况下。对一个特定的目标beanQ?br />TransactionProxyFactoryBean用事务配|自p合proxy定义?q样把配置工作减少为配|一个目标bean以及一?proxy bean的定?br />Q少了interceptor的定义)?此外你也不需要指定事务方法定义在哪一个接口或cM?<beans>
...
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="myProductServiceTarget" class="product.ProductServiceImpl">
<property name="productDao">
<ref bean="myProductDao"/>
</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>
]]>
<struts-config>
<data-sources />
<form-beans >
<form-bean name="logonForm" type="com.xcblcx.struts.form.LogonForm">
<!-- <form-property name="userName" type="java.lang.String"/>
<form-property name="password" type="java.lang.String"/> -->
</form-bean>
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<action
attribute="logonForm"
input="/form/logon.jsp"
name="logonForm"
path="/Logon"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="logon_sc" path="/success.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.xcblcx.struts.ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
</struts-config>
spring的配|文ӞQ相关片D)
<beans>
........
<bean name="/Logon" class="com.xcblcx.struts.action.LogonAction">
<property name="CSCEDAO">
<ref bean="programmerDAOImpl"/>
</property>
</bean>
</bean>
</beans>
注入到action中的programmerDAOImpl没有问题Q我已经使用普通应用程序测试过了?br />现在问题是,q行logon.jsp点击提交后,tomcat报错Q?br />
type Status report
message Servlet LogonAction is not available
description
The requested resource (Servlet LogonAction is not available) is not available.
不知道ؓ什么, q请大家发表意见Q?br />附带问一个问题,关于spring理action的问题:一U是在Struts的Action中直接调用Spring的BeanQ另一U方式是Struts的Action作ؓSpring BeansQ直接注入所需资源Q由Springq行理。U方法更好一点呢Q?/p>