2声明式管理Hibernate本地事务
Spring提供了一种统一的IoC方式来管理Hibernate事务(本地或者分布式事务)。从Spring接手hibernate.cfg.xml(Hibernate的基本配置文件)起,Hibernate事务便轻易交由Spring拖管了。
说明:在上一章介绍IBatis和DAO的时候,曾经针对事务和DAO的关系简单的进行了探讨。通常DAO的粒度应该都是比较细的,即它们只是一些单步的CRUD操作,所以就需要引入一个业务对象来包裹DAO,这样,就可以在业务对象的基础上,提供更粗粒度的事务划分了(比如跨越多个DAO的方法调用进行事务管理)。
为了能对DAO进行更粗粒度的事务控制,需要为其增加一个业务对象。下面给出了该业务对象的接口和实现,如代码10.25~10.26所示。
package chapter10.spring.hibernate;
import chapter10.hibernate.domain.Category;
public interface StockFacade {
public void business1(Category category);
public void someOtherBusiness();
}
代码10.26 BusinessFacadeImpl.java
public class BusinessFacadeImpl implements StockFacade {
private StockDao stockDao;
public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
}
public void business1(Category category) {
stockDao.createCategoryCascade(category);
stockDao.retrieveProductBy(category);
stockDao.deleteCategoryCascade(category);
}
public void someOtherBusiness() {
//other implemention
}
}
接着给出关于事务策略的配置,其中使用了Spring针对Hibernate3给出的HibernateTransactionManager,它提供了Hibernate的本地事务管理策略,如代码10.27所示。
代码10.27 transaction-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">①
<property name="sessionFactory" >
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="business"
class="chapter10.spring.hibernate.BusinessFacadeImpl">
<property name="stockDao">
<ref bean="stockDao"/>
</property>
</bean>
<bean id="businessProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref bean="business" />
</property>
<property name="transactionAttributes">
<props>
<!--运行在当前事务范围内,如果当前没有启动事务,那么创建一个新的事务-->
<prop key="business*">PROPAGATION_REQUIRED</prop>
<!--运行在当前事务范围内,如果当前没有启动事务,那么抛出异常-->
<prop key="someOtherBusiness*">PROPAGATION_MANDATORY</prop>
</props>
</property>
</bean>
</beans>
代码10.28 HibernateTransactionUsageTest.java
package chapter10.spring.hibernate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import chapter10.hibernate.domain.Category;
import junit.framework.TestCase;
public class HibernateTransactionUsageTest extends TestCase {
private StockFacade stockBusiness;
protected void setUp() throws Exception {
String path = "ch10/spring/hibernate/";
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[]{path+"dataAccessContext-support-local.xml",
path+"transaction-context.xml"});
stockBusiness = (StockFacade)ctx.getBean("businessProxy");
}
public void testTransctionUsage() {
Category category = new Category("RABBIT");
category.setName("Rabbit");
category.setDescn("Desciption of Rabbit");
stockBusiness.business1(category);
}
}