Spring對Hibernate的session生效期(事物提交管理)介紹


  在Hibernate中我們每次進行一個操作的的時候我們都是要先開啟事務,然后進行數據操作,然后提交事務,關閉事務,這樣做的原因是因為 Hibernate默認的事務自動提交是false,它是需要人為的手動提交事務,假如你不想每次都手動提交事務的話,你可以在 hibernate.cfg.xml我文件中把它設置為事務自動提交:
 
<propertyname="hibernate.connection.autocommit">true</property>

 

   當我們Spring對我們的Hibernate進行整合之后,我們的代碼又出現了什么變化呢?
 
  整合,之后,我們不再是每次都去拿Session進行數據操作了,也不需要每次都開啟事務,提交事務了,我們只需要Spring給我們提供的一個HibernateTemplate,我們直接用這個類里面給我們提供的數據操作方法就可以操作數據了。我們在也看不到關於事務的代碼了。
 
 
   那Spring究竟有沒有在他的操作方法里面封裝事務處理呢?有的人直接 HibernateTemplate里面提供的方法操作數據,成功了,有的人卻又失敗了,這到底是怎么回事呢?
 
  其實這里要看我們是怎樣集成我們的 Hibernate和Spring
  1.如果在集成的過程中,我們拋棄了hibernate.cfg.xml文件,直接在Spring的的配置文件中進行配置數據源的話,那你直接用HibernateTemplate里面提供的方法是 可以成功操作數據的.
  2.如果你還是用hibernate.cfg.xml來配置數據源,在Spring的配置文件中引用hibernate.cfg.xml文件, 那么你不能成功,這其中的原因就是因為如果你用 hibernate.cfg.xml文件配置數據源,就像我們前面說的,Hibernate默認是手動提交事務,而HibernateTemplatel 提供的方法里面並沒有提供事務提交,而如果你用Spring的配置文件來配置數據源,Sping默認是自動提交的,所以就會成功,如果你想把Spring 設置為手動提交你可以在起配置文件中進行配置:
<property name="defaultAutoCommit">
  <value>false</value>
</property>

 

  縱然我們把它的事務提交方式設置為自動,它可以進行數據操作,但是這樣並不滿足我們實際的業務需求,因為有時候在我保存一個數據之后,我希望他能繼續保存另一條數據,我希望在保存完兩條或者多條之后一起進行事務提交,這樣即使出錯,我們可以回滾,取保數據的一致性,要么都成功要么都失敗,這時候我們就不能每保存完一條數據之后 事務就自動提交,因為這樣它們不在同一個事務當中,我們不能保證數據的一致行。所以這時候我們就需要手動的來配置我們的事務,這就需要用到Spring為Hibernate提供的事務管理機制,Spring提供的事務管理可以分為兩類:編程式的和聲明式的,編程式,其實就是在代碼里面來控制,像Hibernate操作數據一樣,開啟事務,提交事務,這種方式有一定的局限性,所以我們一般是用聲明式來配置我們的事務。
  
   一下對spring的食物簡單關聯下,具體詳情和使用查看spring的事物管理帖子
 
   聲明式事務配置主要分以下幾步:
 
1、聲明式事務配置
 
(1) 配置事務管理器;
 
(2)事務的傳播特性;
 
(3)那些類那些方法使用事務。
 
<!-- 配置事務管理器 指定其作用的sessionFactory把事務交給Spring去處理 -->
 
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
      <ref bean="sessionFactory"/>
  </property>
</bean>
 
<!-- 配置事務的傳播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
 
<!-- 那些類的哪些方法參與事務 -->
<aop:config>
  <aop:pointcut id="allServiceMethod" expression="execution(* com.coe.service.*.*(..))"/>
  <aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice"/>
</aop:config>

 

  我們在配置事務的時候,我們一般是把事務邊界設置到service層,也就是你的業務邏輯層,因為我們很多時候都是在我們的業務邏輯層來完成我們一些列的數據操作,如果放到Dao數據層,其粒度太小了。另外,如果我們把事務配置在業務邏輯層的話,對我們的二級緩存也是有好處的,這個大家以后實際操作的時候會發現。
 
2、編寫業務邏輯方法
 
  這時候我們就可以在我們業務邏輯層用HibernateTemplate里面提供的數據操作方法來編寫我們的業務邏輯方法了,當然我們的方法必須要是以我們事務配置里面配置的一樣,用save,delete,update,get做我們的方法的開頭。需要注意的是,默認情況下運行期異常才會回滾(包括繼承了RuntimeException子類),普通異常是不會滾的。
 
最后我們順便總結一下事務的幾種傳播特性:
 
1. PROPAGATION_REQUIRED: 如果存在一個事務,則支持當前事務。如果沒有事務則開啟;
 
2. PROPAGATION_SUPPORTS: 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行;
 
3. PROPAGATION_MANDATORY: 如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常;
 
4. PROPAGATION_REQUIRES_NEW: 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起;
 
5. PROPAGATION_NOT_SUPPORTED: 總是非事務地執行,並掛起任何存在的事務;
 
6. PROPAGATION_NEVER: 總是非事務地執行,如果存在一個活動事務,則拋出異常;
 
7. PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM