2012-10-26 112 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