Spring事务配置在DAO和Service层
【转载自http://www.blogjava.net/hk2000c/archive/2007/11/01/157508.html】
【感谢原作者:hk2000c】
Spring通过AOP实现声明式事务管理。通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。
PlatformTransactionManager:
HibernateTransactionManager需要一个SessionFactory的引用
JtaTransactionManager
一.把事务放置在了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>
<!—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>
<!—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方法:按顺序执行对数据库的数据查询,数据删除,数据插入数据库,如果哪一步出异常(运行时异常),以上三个操作都将事务回滚。