2012-10-26 83 views
4

我刚开始做一个使用spring和hibernate的项目。我的DAO图层类扩展了HibernateDaoSupport。我们不使用注释。 此前,我们使用的是struts,因此我们使用了由Session类提供的getTransaction,commit,rollback等方法。 我的要求很简单,对于所有的DAO类,如果有异常,则回滚否则提交。请建议介绍spring事务管理的最简单方法。Spring Hibernate事务管理

回答

12

有些事情不清楚你的问题。我的解释如下基于以下的假设 -

  • 您正在使用的弹簧来创建数据源和会话工厂
  • 您正在使用Java 5或以上,并可以使用注解。

下面是你的弹簧配置的样子。

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 
    <property name="url" value="jdbc:hsqldb:hsql://localhost:9001" /> 
    <property name="username" value="sa" /> 
    <property name="password" value="" /> 
</bean> 

<bean id="mySessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="myDataSource" /> 
    <property name="mappingResources"> 
     <list> 
      <value>product.hbm.xml</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <value> 
      hibernate.dialect=org.hibernate.dialect.HSQLDialect 
     </value> 
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="mySessionFactory" /> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

一旦设置好了,你可以在你的DAO方法上使用spring transactional annotations,如下所示。 Spring将处理启动事务,提交事务或在抛出异常时回滚事务。如果您有商业服务,则最好在您的服务上使用交易注释,而不是DAO。

@Transactional(propagation=Propagation.REQUIRED) 
public class MyTestDao extends HibernateDaoSupport {  
public void saveEntity(Entity entity){ 
    getHibernateTemplate().save(entity); 
} 
@Transactional(readOnly=true) 
public Entity getEntity(Integer id){ 
    return getHibernateTemplate().get(Entity.class, id); 
} 
} 

下面的代码显示了如何使用spring对AOP的支持而不是注释来实现事务管理。

<!-- Define your 'myDatasource' bean and 'mySessionFactory' bean as shown in previous code snippet --> 
<!-- Then follow the steps shown below --> 

<bean id="transactionManager" 
class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory" ref="mySessionFactory" /> 

<!-- this is the dao object that we want to make transactional --> 
<bean id="testDao" class="com.xyz.daos.MyTestDao" /> 

<!-- the transactional advice --> 
<tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <!-- all methods starting with 'get' are read-only --> 
     <tx:method name="get*" read-only="true" /> 
     <!-- other methods use the default transaction settings (see below) --> 
     <tx:method name="*" propagation="REQUIRED" /> 
    </tx:attributes> 
</tx:advice> 

<!-- ensure that the above transactional advice runs for any execution of 
    a method in 'daos' package--> 
<aop:config> 
    <aop:pointcut id="allDaoMethods" 
     expression="execution(* com.xyz.daos.*(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethods" /> 
</aop:config> 

有关详细信息,请参阅 - Spring Declarative Transactions

+0

非常感谢一个明确和准确的答案。这个例子是一个使用注释的快速演示。但我在这里注释每种方法。我需要所有类的通用行为。是否有可能用xml来定义这个东西,比如说......我所有的DAO都会遵循..... propagation = Propagation.REQUIRED .......不需要帮助注释。 –

+0

我猜注解是未来的唯一方法。为我的要求执行相同的操作。 –

+0

你确实可以用Spring aop获得你需要的行为。如果您决定使用注释,需要注意的是您不必注释每种方法。你可以注释你的类,所有的方法都会继承这个行为,你可以注释一个方法来覆盖这个行为。 – Sashi