自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

解析Hibernate中的事務(wù)管理

開發(fā) 后端
Hibernate本身并不具備事務(wù)管理能力。在事務(wù)管理層,Hibernate將其委托給底層的JDBC或者JTA,以實(shí)現(xiàn)事務(wù)管理和調(diào)度功能。本文對(duì)Hibernate-事務(wù)管理做出詳細(xì)的解析。

Hibernate 是JDBC 的輕量級(jí)封裝,本身并不具備事務(wù)管理能力。在事務(wù)管理層,Hibernate將其委托給底層的JDBC或者JTA,以實(shí)現(xiàn)事務(wù)管理和調(diào)度功能。

Hibernate的默認(rèn)事務(wù)處理機(jī)制基于JDBC Transaction。我們也可以通過配置文
件設(shè)定采用JTA作為事務(wù)管理實(shí)現(xiàn):

Java代碼

   

……

net.sf.hibernate.transaction.JTATransactionFactory


……



……

net.sf.hibernate.transaction.JTATransactionFactory


……


基于JDBC的事務(wù)管理將事務(wù)管理委托給JDBC 進(jìn)行處理無疑是最簡(jiǎn)單的實(shí)現(xiàn)方式,Hibernate 對(duì)于JDBC事務(wù)的封裝也極為簡(jiǎn)單。
我們來看下面這段代碼:
Java代碼
   session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
……
tx.commit();

 

session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
……
tx.commit();
從JDBC層面而言,上面的代碼實(shí)際上對(duì)應(yīng)著:
Java代碼
Connection dbconn = getConnection();
dbconn.setAutoCommit(false);
……
dbconn.commit();

 

Connection dbconn = getConnection();
dbconn.setAutoCommit(false);
……
dbconn.commit();


就是這么簡(jiǎn)單,Hibernate并沒有做更多的事情(實(shí)際上也沒法做更多的事情),只是將這樣的JDBC代碼進(jìn)行了封裝而已。
這里要注意的是,在sessionFactory.openSession()中,hibernate會(huì)初始化數(shù)據(jù)庫(kù)連接,與此同時(shí),將其AutoCommit 設(shè)為關(guān)閉狀態(tài)(false)。而其后,在Session.beginTransaction 方法中,Hibernate 會(huì)再次確認(rèn)Connection 的AutoCommit 屬性被設(shè)為關(guān)閉狀態(tài)( 為了防止用戶代碼對(duì)session 的Connection.AutoCommit屬性進(jìn)行修改)。
這也就是說,我們一開始從SessionFactory獲得的session,其自動(dòng)提交屬性就已經(jīng)被關(guān)閉(AutoCommit=false),下面的代碼將不會(huì)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生任何效果:
Java代碼
    session = sessionFactory.openSession();
session.save(user);
session.close();

 

session = sessionFactory.openSession();
session.save(user);
session.close();


這實(shí)際上相當(dāng)于 JDBC Connection的AutoCommit屬性被設(shè)為false,執(zhí)行了若干JDBC操作之后,沒有調(diào)用commit操作即將Connection關(guān)閉。如果要使代碼真正作用到數(shù)據(jù)庫(kù),我們必須顯式的調(diào)用Transaction指令:
Java代碼
    session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();


基于JTA的事務(wù)管理

JTA 提供了跨Session 的事務(wù)管理能力。這一點(diǎn)是與JDBC Transaction 最大的差異。
JDBC事務(wù)由Connnection管理,也就是說,事務(wù)管理實(shí)際上是在JDBC Connection中實(shí)現(xiàn)。事務(wù)周期限于Connection的生命周期之類。同樣,對(duì)于基于JDBC Transaction的Hibernate 事務(wù)管理機(jī)制而言,事務(wù)管理在Session 所依托的JDBC Connection中實(shí)現(xiàn),事務(wù)周期限于Session的生命周期。
JTA 事務(wù)管理則由 JTA 容器實(shí)現(xiàn),JTA 容器對(duì)當(dāng)前加入事務(wù)的眾多Connection 進(jìn)
行調(diào)度,實(shí)現(xiàn)其事務(wù)性要求。JTA的事務(wù)周期可橫跨多個(gè)JDBC Connection生命周期。
同樣對(duì)于基于JTA事務(wù)的Hibernate而言,JTA事務(wù)橫跨可橫跨多個(gè)Session。
JTA 事務(wù)是由JTA Container 維護(hù),而參與事務(wù)的Connection無需對(duì)事務(wù)管理進(jìn)行干涉。這也就是說,如果采用JTA Transaction,我們不應(yīng)該再調(diào)用HibernateTransaction功能。
上面基于JDBC Transaction的正確代碼,這里就會(huì)產(chǎn)生問題:
Java代碼

   public class ClassA{
public void saveUser(User user){
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();
}
}
public class ClassB{
public void saveOrder(Order order){
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(order);
tx.commit();
session.close();
}
}
public class ClassC{
public void save(){
……
UserTransaction tx = new InitialContext().lookup(“……”);
ClassA.save(user);
ClassB.save(order);
tx.commit();
……
}
}
public class ClassA{
public void saveUser(User user){
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();
}
}
public class ClassB{
public void saveOrder(Order order){
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(order);
tx.commit();
session.close();
}
}
public class ClassC{
public void save(){
……
UserTransaction tx = new InitialContext().lookup(“……”);
ClassA.save(user);
ClassB.save(order);
tx.commit();
……
}
}

這里有兩個(gè)類ClassA和ClassB,分別提供了兩個(gè)方法:saveUsersaveOrder,
用于保存用戶信息和訂單信息。在ClassC中,我們接連調(diào)用了ClassA.saveUser方法和ClassB.saveOrder 方法,同時(shí)引入了JTA 中的UserTransaction 以實(shí)現(xiàn)ClassC.save方法中的事務(wù)性。問題出現(xiàn)了,ClassA 和ClassB 中分別都調(diào)用了Hibernate 的Transaction 功能。在Hibernate 的JTA 封裝中,Session.beginTransaction 同樣也執(zhí)行了InitialContext.lookup方法獲取UserTransaction實(shí)例,Transaction.commit方法同樣也調(diào)用了UserTransaction.commit方法。實(shí)際上,這就形成了兩個(gè)嵌套式的JTA Transaction:ClassC 申明了一個(gè)事務(wù),而在ClassC 事務(wù)周期內(nèi),ClassA 和ClassB也企圖申明自己的事務(wù),這將導(dǎo)致運(yùn)行期錯(cuò)誤。因此,如果決定采用JTA Transaction,應(yīng)避免再重復(fù)調(diào)用Hibernate 的
Transaction功能,上面的代碼修改如下:
Java代碼
   public class ClassA{
public void save(TUser user){
session = sessionFactory.openSession();
session.save(user);
session.close();
}
……
}
public class ClassB{
public void save (Order order){
session = sessionFactory.openSession();
session.save(order);
session.close();
}
……
}
public class ClassC{
public void save(){
……
UserTransaction tx = new InitialContext().lookup(“……”);
classA.save(user);
classB.save(order);
tx.commit();
……
}
}
public class ClassA{
public void save(TUser user){
session = sessionFactory.openSession();
session.save(user);
session.close();
}
……
}
public class ClassB{
public void save (Order order){
session = sessionFactory.openSession();
session.save(order);
session.close();
}
……
}
public class ClassC{
public void save(){
……
UserTransaction tx = new InitialContext().lookup(“……”);
classA.save(user);
classB.save(order);
tx.commit();
……
}
}
上面代碼中的ClassC.save方法,也可以改成這樣:
Java代碼
public class ClassC{
public void save(){
……
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
classA.save(user);
classB.save(order);
tx.commit();
……
}
}
public class ClassC{
public void save(){
……
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
classA.save(user);
classB.save(order);
tx.commit();
……
}
}

實(shí)際上,這是利用Hibernate來完成啟動(dòng)和提交UserTransaction的功能,但這樣的做法比原本直接通過InitialContext獲取UserTransaction 的做法消耗了更多的資源,得不償失。
在EJB 中使用JTA Transaction 無疑最為簡(jiǎn)便,我們只需要將save 方法配置為JTA事務(wù)支持即可,無需顯式申明任何事務(wù),下面是一個(gè)Session Bean的save方法,它的事務(wù)屬性被申明為“Required”,EJB容器將自動(dòng)維護(hù)此方法執(zhí)行過程中的事務(wù):

Java代碼

   /**
* @ejb.interface-method
* view-type="remote"
*
* @ejb.transaction type = "Required"
**/
public void save(){

//EJB環(huán)境中,通過部署配置即可實(shí)現(xiàn)事務(wù)申明,而無需顯式調(diào)用事務(wù)
   classA.save(user);
classB.save(log);
}

//方法結(jié)束時(shí),如果沒有異常發(fā)生,則事務(wù)由EJB容器自動(dòng)提交。

您正在閱讀:解析Hibernate中的事務(wù)管理

【編輯推薦】

  1. Hibernate框架如何實(shí)現(xiàn)ORM
  2. Hibernate/JPA成功使用的十點(diǎn)心得
  3. 優(yōu)化Hibernate性能的幾點(diǎn)建議
責(zé)任編輯:張攀 來源: javaeye論壇
相關(guān)推薦

2009-09-25 12:59:53

Hibernate事務(wù)

2009-09-29 09:44:52

Hibernate事務(wù)

2009-09-23 17:48:00

Hibernate事務(wù)

2022-08-04 08:46:16

單體架構(gòu)微服務(wù)事務(wù)管理

2009-06-03 10:49:48

Hibernate事務(wù)

2025-02-08 10:56:18

2024-06-05 06:51:11

2023-10-08 08:28:10

Spring事務(wù)管理

2009-06-17 14:57:11

Spring事務(wù)管理

2009-06-30 16:57:42

Spring事務(wù)管理

2009-07-17 14:03:34

ibatis DAO事務(wù)管理

2023-03-27 10:40:09

2009-06-08 17:56:00

SpringJDBC事務(wù)

2025-02-21 08:00:00

事務(wù)管理SpringBootJava

2014-08-25 09:12:47

Spring事務(wù)管理

2009-06-17 14:43:47

Spring框架Spring事務(wù)管理

2010-03-29 13:34:15

ibmdwSpring

2010-03-23 08:46:40

Spring

2009-02-11 13:08:29

事務(wù)提交事務(wù)管理Spring

2009-02-11 11:14:31

事務(wù)管理事務(wù)開始Spring
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)