- <!--第一部分 数据源-->
- <bean id="dataSource"
- class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName">
- <value>com.mysql.jdbc.Driver</value>
- </property>
- <property name="url">
- <value>jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8</value>
- </property>
- <property name="username">
- <value>root</value>
- </property>
- <property name="password">
- <value>root</value>
- </property>
- </bean>
- <!--第二部分 hibernate的配置-->
- <bean id="exampleHibernateProperties"
- class="org.springframework.beans.factory.config.PropertiesFactoryBean">
- <property name="properties">
- <props>
- <prop key="hibernate.hbm2ddl.auto">update</prop>
- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
- <prop key="hibernate.query.substitutions">true '0', false '1'</prop>
- <prop key="hibernate.show_sql">true</prop>
- <prop key="hibernate.c3p0.minPoolSize">5</prop>
- <prop key="hibernate.c3p0.maxPoolSize">20</prop>
- <prop key="hibernate.c3p0.timeout">600</prop>
- <prop key="hibernate.c3p0.max_statement">50</prop>
- <prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
- </props>
- </property>
- </bean>
- <!--第三部分 hibernate的sessionFactory 一个关联于特定数据库的全局工厂-->
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource" />//先前定义的数据源
- </property>
- <property name="mappingResources">
- <list>
- <value>Test.hbm.xml</value>//hibernate O/R map文件
- </list>
- </property>
- <property name="hibernateProperties">
- <ref bean="exampleHibernateProperties" />//先前定义的hibernate 配置
- </property>
- </bean>
- <!--第四部分 事务 transactionManager-->
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager"
- abstract="false" singleton="true" lazy-init="default"
- autowire="default" dependency-check="default">
- <property name="sessionFactory">
- <ref bean="sessionFactory" />//先前定义的sessinFactory
- </property>
- </bean>
- <!--第五部分 Dao 抽象-->
- <bean id="baseDao" abstract="true" singleton="false">
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- 定义baseDao的好处就是在以下的Dao中再不用每个bean 都要注入sessionFactory了
- <!--第六部分 Dao-->
- <bean id="testDao" parent="baseDao" //继承于先前定义的Dao 抽象
- class="ssh.naxj.dao.TestDao" singleton="true"/>
- <!--第七部分 定义 Target(BO)-->
- <bean id="testBoTarget" class="ssh.naxj.bo.TestBo" singleton="true">
- <property name="testDao" ref="testDao"/>//IOC 注入testDao
- </bean>
- <!--第八部分 使用事务的BO-->
- <bean id="testBo"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref local="transactionManager"/>//transactionManager
- </property>
- <property name="target"><ref local="testBoTarget"/></property>//Target
- <property name="transactionAttributes">
- <props>
- <prop key="*">PROPAGATION_REQUIRED</prop>//“*”为所有的方法使用事务
- </props>
- </property>
- </bean>
<!--第一部分 数据源-->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
<!--第二部分 hibernate的配置-->
<bean id="exampleHibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true '0', false '1'</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
</props>
</property>
</bean>
<!--第三部分 hibernate的sessionFactory 一个关联于特定数据库的全局工厂-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />//先前定义的数据源
</property>
<property name="mappingResources">
<list>
<value>Test.hbm.xml</value>//hibernate O/R map文件
</list>
</property>
<property name="hibernateProperties">
<ref bean="exampleHibernateProperties" />//先前定义的hibernate 配置
</property>
</bean>
<!--第四部分 事务 transactionManager-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="sessionFactory">
<ref bean="sessionFactory" />//先前定义的sessinFactory
</property>
</bean>
<!--第五部分 Dao 抽象-->
<bean id="baseDao" abstract="true" singleton="false">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
定义baseDao的好处就是在以下的Dao中再不用每个bean 都要注入sessionFactory了
<!--第六部分 Dao-->
<bean id="testDao" parent="baseDao" //继承于先前定义的Dao 抽象
class="ssh.naxj.dao.TestDao" singleton="true"/>
<!--第七部分 定义 Target(BO)-->
<bean id="testBoTarget" class="ssh.naxj.bo.TestBo" singleton="true">
<property name="testDao" ref="testDao"/>//IOC 注入testDao
</bean>
<!--第八部分 使用事务的BO-->
<bean id="testBo"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>//transactionManager
</property>
<property name="target"><ref local="testBoTarget"/></property>//Target
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>//“*”为所有的方法使用事务
</props>
</property>
</bean>
OK,大功告成...
======================================================================
Spring配置事务在DAO层和业务逻辑层
Spring通过AOP实现声明式事务管理。通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。事务属性含有上面描述的事务定义。
HibernateTransactionManager需要一个SessionFactory的引用
一.把事务放置在了DAO层:
- <!—hibernateTransactionManager-->
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory">
- <ref local="sessionFactory" />
- </property>
- </bean>
- <!—DAO层接口实现-->
- <bean id="companyDAOTarget"
- class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">
- <property name="sessionFactory">
- <ref local="sessionFactory" />
- </property>
- </bean>
- <!—spring对DAO层的事务代理-->
- <bean id="companyDAOProxy"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- </property>
- <property name="target">
- <ref local="companyDAOTarget" />
- </property>
- <property name="transactionAttributes">
- <props>
- <prop key="insert*">PROPAGATION_REQUIRED</prop>
- <prop key="delete*">PROPAGATION_REQUIRED</prop>
- <prop key="find*">
- PROPAGATION_REQUIRED,readOnly
- </prop>
- </props>
- </property>
- </bean>
- <!—业务层接口实现,把DAO注入到Service里面-->
- <bean name="companyManageTarget"
- class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">
- <property name="companyDAO">
- <ref bean="companyDAOProxy" />
- </property>
- </bean>
- <!—spring对Service层的代理-->
- <bean id="companyManageProxy"
- class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces">
- <value>com.vstsoft.querycompany.service.CompanyManage</value>
- </property>
- <property name="target">
- <ref bean="companyManageTarget" />
- </property>
- </bean>
- <!—配置struts访问,把service层注入到action里面-->
- <bean name="/company"
- class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">
- <property name="companyManage">
- <ref local="companyManageProxy" />
- </property>
- </bean>
<!—hibernateTransactionManager-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!—DAO层接口实现-->
<bean id="companyDAOTarget"
class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!—spring对DAO层的事务代理-->
<bean id="companyDAOProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="companyDAOTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="find*">
PROPAGATION_REQUIRED,readOnly
</prop>
</props>
</property>
</bean>
<!—业务层接口实现,把DAO注入到Service里面-->
<bean name="companyManageTarget"
class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">
<property name="companyDAO">
<ref bean="companyDAOProxy" />
</property>
</bean>
<!—spring对Service层的代理-->
<bean id="companyManageProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.vstsoft.querycompany.service.CompanyManage</value>
</property>
<property name="target">
<ref bean="companyManageTarget" />
</property>
</bean>
<!—配置struts访问,把service层注入到action里面-->
<bean name="/company"
class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">
<property name="companyManage">
<ref local="companyManageProxy" />
</property>
</bean>
二.把事务放置在了Service层:
- <!—jtaTransactionManager-->
- <bean id="jtaTransactionManager"
- class="org.springframework.transaction.jta.JtaTransactionManager" />
- <!—DAO层接口实现-->
- <bean id="companyDAOTarget"
- class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">
- <property name="sessionFactory">
- <ref local="sessionFactory" />
- </property>
- </bean>
- <!—spring对DAO层的代理-->
- <bean id="companyDAOProxy"
- class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces">
- <value>com.vstsoft.querycompany.dao.CompanyDAO</value>
- </property>
- <property name="target">
- <ref bean="companyDAOTarget" />
- </property>
- </bean>
- <!—业务层接口实现,把DAO注入到Service里面-->
- <bean name="companyManageTarget"
- class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">
- <property name="companyDAO">
- <ref bean="companyDAOProxy" />
- </property>
- </bean>
- <!—spring代理业务层的事务管理-->
- <bean id="companyManageProxy"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref local="jtaTransactionManager" />
- </property>
- <property name="transactionAttributes">
- <props>
- <prop key="set*">PROPAGATION_REQUIRED</prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
- </props>
- </property>
- <property name="target">
- <ref bean="companyManageTarget" />
- </property>
- </bean>
- <!—配置struts访问,把service层注入到action里面-->
- <bean name="/company"
- class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">
- <property name="companyManage">
- <ref local="companyManageProxy" />
- </property>
- </bean>
<!—jtaTransactionManager-->
<bean id="jtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
<!—DAO层接口实现-->
<bean id="companyDAOTarget"
class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!—spring对DAO层的代理-->
<bean id="companyDAOProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.vstsoft.querycompany.dao.CompanyDAO</value>
</property>
<property name="target">
<ref bean="companyDAOTarget" />
</property>
</bean>
<!—业务层接口实现,把DAO注入到Service里面-->
<bean name="companyManageTarget"
class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">
<property name="companyDAO">
<ref bean="companyDAOProxy" />
</property>
</bean>
<!—spring代理业务层的事务管理-->
<bean id="companyManageProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="jtaTransactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="set*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
<property name="target">
<ref bean="companyManageTarget" />
</property>
</bean>
<!—配置struts访问,把service层注入到action里面-->
<bean name="/company"
class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">
<property name="companyManage">
<ref local="companyManageProxy" />
</property>
</bean>
在service层的接口实现CompanyManageImpl里面有个setData方法:按顺序执行数据查询,数据删除,数据插入数据库行为,如果哪一步出异常(运行时异常),事务回滚,只有所有行为都没成功,事务提交。
===========================================================================
简单来说,就是因为lazy的问题,采用了org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,
但是这东东不太友好哦!
目前我的解决办法如下:
spring原码不用改,
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter只管在web.xml文件里加载,不用带任何参数,
在业务层继承一个父类来管理事务:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
- "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <!--Base TransactionProxyed Service Bean-->
- <bean id="baseTxService"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
- abstract="true">
- <property name="transactionManager" ref="transactionManager"/>
- <property name="proxyTargetClass" value="true"/>
- <property name="transactionAttributes">
- <props>
- <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="save*">PROPAGATION_REQUIRED</prop>
- <prop key="update*">PROPAGATION_REQUIRED</prop>
- <prop key="remove*">PROPAGATION_REQUIRED</prop>
- <prop key="set*">PROPAGATION_REQUIRED</prop>
- <prop key="change*">PROPAGATION_REQUIRED</prop>
- <prop key="delete*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- <property name="preInterceptors">
- <list>
- <ref bean="methodSecurityInterceptor"/>
- </list>
- </property>
- </bean>
- </beans>
- //-----------------------------------------------------------------
- <bean id="infopathManager" parent="baseTxService" autowire="byName">
- <property name="target">
- <bean class="com.gdlinkway.ebop.infopath.manager.InfopathManager"/>
- </property>
- </bean>