程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Hibernate的事務和並發02

Hibernate的事務和並發02

編輯:JAVA編程入門知識

  12.2.1.非托管環境

  如果Hibernat持久層運行在一個非托管環境中,數據庫連接通常由Hibernate的連接池機制 來處理。

  

代碼內容
session/transaction處理方式如下所示:
//Non-managed environment idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}

  你不需要顯式flush() Session - 對commit()的調用會自動觸發session的同步。

  調用 close() 標志session的結束。 close()方法重要的暗示是,session釋放了JDBC連接。

  這段Java代碼是可移植的,可以在非托管環境和JTA環境中運行。

  你很可能從未在一個標准的應用程序的業務代碼中見過這樣的用法;致命的(系統)異常應該總是 在應用程序“頂層”被捕獲。換句話說,執行Hibernate調用的代碼(在持久層)和處理 RuntimeException異常的代碼(通常只能清理和退出應用程序)應該在不同 的應用程序邏輯層。這對於你設計自己的軟件系統來說是一個挑戰,只要有可能,你就應該使用 J2EE/EJB容器服務。異常處理將在本章稍後進行討論。

  請注意,你應該選擇 org.hibernate.transaction.JDBCTransactionFactory (這是默認選項).

  12.2.2.使用JTA

  如果你的持久層運行在一個應用服務器中(例如,在EJB session beans的後面),Hibernate獲取 的每個數據源連接將自動成為全局JTA事務的一部分。Hibernate提供了兩種策略進行JTA集成。

  如果你使用bean管理事務(BMT),可以通過使用Hibernate的 Transaction API來告訴 應用服務器啟動和結束BMT事務。因此,事務管理代碼和在非托管環境下是一樣的。

  

代碼內容
// BMT idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
在CMT方式下,事務聲明是在session bean的部署描述符中,而不需要編程。 除非你設置了屬性hibernate.transaction.flush_before_completion和 hibernate.transaction.auto_close_session為true, 否則你必須自己同步和關閉Session。Hibernate可以為你自動同步和關閉 Session。你唯一要做的就是當發生異常時進行事務回滾。幸運的是, 在一個CMT bean中,事務回滾甚至可以由容器自動進行,因為由session bean方法拋出的未處理的 RuntimeException異常可以通知容器設置全局事務回滾。這意味著 在CMT中,你完全無需使用Hibernate的Transaction API 。

  請注意,當你配置Hibernate事務工廠的時候,在一個BMT session bean中,你應該選擇 org.hibernate.transaction.JTATransactionFactory,在一個 CMT session bean中選擇org.hibernate.transaction.CMTTransactionFactory。 記住,同時也要設置org.hibernate.transaction.manager_lookup_class。

  如果你使用CMT環境,並且讓容器自動同步和關閉session,你可能也希望在你代碼的不同部分使用 同一個session。一般來說,在一個非托管環境中,你可以使用一個ThreadLocal 變量來持有這個session,但是單個EJB方法調用可能會在不同的線程中執行(舉例來說,一個session bean調用另一個session bean)。如果你不想在應用代碼中被傳遞Session對 象實例的問題困擾的話,那麼SessionFactory 提供的 getCurrentSession()方法就很適合你,該方法返回一個綁定到JTA事務 上下文環境中的session實例。這也是把Hibernate集成到一個應用程序中的最簡單的方法!這個“當 前的”session總是可以自動同步和自動關閉(不考慮上述的屬性設置)。我們的session/transaction 管理代碼減少到如下所示:

  

代碼內容
// CMT idiom
Session sess = factory.getCurrentSession();
// do some work
...

  換句話來說,在一個托管環境下,你要做的所有的事情就是調用 SessionFactory.getCurrentSession(),然後進行你的數據訪問,把其余的工作 交給容器來做。事務在你的session bean的部署描述符中以可聲明的方式來設置。session的生命周期完全 由Hibernate來管理。

  對after_statement連接釋放方式有一個警告。因為JTA規范的一個很愚蠢的限制,Hibernate不可能自動清理任何未關閉的ScrollableResults 或者Iterator,它們是由scroll()或iterate()產生的。你must通過在finally塊中,顯式調用ScrollableResults.close()或者Hibernate.close(Iterator)方法來釋放底層數據庫游標。(當然,大部分程序完全可以很容易的避免在CMT代碼中出現scroll()或iterate()。)

  • 首頁
  • 上一頁
  • 1
  • 2
  • 3
  • 下一頁
  • 尾頁
  • 共3頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved