亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1593 | 回復: 0
打印 上一主題 下一主題

hibernate的基于JDBC和JTA的事務(wù)管理機制的分析 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-09-21 22:24 |只看該作者 |倒序瀏覽
Hibernate 是JDBC 的輕量級封裝,本身并不具備事務(wù)管理能力。在事務(wù)管理層,
Hibernate將其委托給底層的JDBC或者JTA,以實現(xiàn)事務(wù)管理和調(diào)度功能。
Hibernate的默認事務(wù)處理機制基于JDBC Transaction。我們也可以通過配置文
件設(shè)定采用JTA作為事務(wù)管理實現(xiàn):
Java代碼
[/url]
   
   
……   
   
net.sf.hibernate.transaction.JTATransactionFactory   
   
   
……   
   
   
……
net.sf.hibernate.transaction.JTATransactionFactory
……
基于JDBC的事務(wù)管理將事務(wù)管理委托給JDBC 進行處理無疑是最簡單的實現(xiàn)方式,Hibernate 對于JDBC事務(wù)的封裝也極為簡單。
我們來看下面這段代碼:
Java代碼
[url=http://www.javaeye.com/topic/177988]

session = sessionFactory.openSession();   
Transaction tx = session.beginTransaction();   
……   
tx.commit();   
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
……
tx.commit();
從JDBC層面而言,上面的代碼實際上對應(yīng)著:
Java代碼
[/url]
Connection dbconn = getConnection();   
dbconn.setAutoCommit(false);   
……   
dbconn.commit();   
Connection dbconn = getConnection();
dbconn.setAutoCommit(false);
……
dbconn.commit();
就是這么簡單,Hibernate并沒有做更多的事情(實際上也沒法做更多的事情),只是將這樣的JDBC代碼進行了封裝而已。
這里要注意的是,在sessionFactory.openSession()中,hibernate會初始化數(shù)據(jù)庫連接,與此同時,將其AutoCommit 設(shè)為關(guān)閉狀態(tài)(false)。而其后,在Session.beginTransaction 方法中,Hibernate 會再次確認Connection 的AutoCommit 屬性被設(shè)為關(guān)閉狀態(tài)( 為了防止用戶代碼對session 的Connection.AutoCommit屬性進行修改)。
這也就是說,我們一開始從SessionFactory獲得的session,其自動提交屬性就已經(jīng)被關(guān)閉(AutoCommit=false),下面的代碼將不會對數(shù)據(jù)庫產(chǎn)生任何效果:
Java代碼
[url=http://www.javaeye.com/topic/177988]

session = sessionFactory.openSession();   
session.save(user);   
session.close();   
session = sessionFactory.openSession();
session.save(user);
session.close();
這實際上相當于 JDBC Connection的AutoCommit屬性被設(shè)為false,執(zhí)行了若干JDBC操作之后,沒有調(diào)用commit操作即將Connection關(guān)閉。如果要使代碼真正作用到數(shù)據(jù)庫,我們必須顯式的調(diào)用Transaction指令:
Java代碼
[/url]
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ù)管理能力。這一點是與JDBC Transaction 最大的差異。
JDBC事務(wù)由Connnection管理,也就是說,事務(wù)管理實際上是在JDBC Connection中實現(xiàn)。事務(wù)周期限于Connection的生命周期之類。同樣,對于基于JDBC Transaction的Hibernate 事務(wù)管理機制而言,事務(wù)管理在Session 所依托的JDBC Connection中實現(xiàn),事務(wù)周期限于Session的生命周期。
JTA 事務(wù)管理則由 JTA 容器實現(xiàn),JTA 容器對當前加入事務(wù)的眾多Connection 進
行調(diào)度,實現(xiàn)其事務(wù)性要求。JTA的事務(wù)周期可橫跨多個JDBC Connection生命周期。
同樣對于基于JTA事務(wù)的Hibernate而言,JTA事務(wù)橫跨可橫跨多個Session。
JTA 事務(wù)是由JTA Container 維護,而參與事務(wù)的Connection無需對事務(wù)管理進行干涉。這也就是說,如果采用JTA Transaction,我們不應(yīng)該再調(diào)用HibernateTransaction功能。
上面基于JDBC Transaction的正確代碼,這里就會產(chǎn)生問題:
Java代碼
[url=http://www.javaeye.com/topic/177988]

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();
……
}
}
這里有兩個類ClassA和ClassB,分別提供了兩個方法:saveUsersaveOrder,
用于保存用戶信息和訂單信息。在ClassC中,我們接連調(diào)用了ClassA.saveUser方法和ClassB.saveOrder 方法,同時引入了JTA 中的UserTransaction 以實現(xiàn)ClassC.save方法中的事務(wù)性。問題出現(xiàn)了,ClassA 和ClassB 中分別都調(diào)用了Hibernate 的Transaction 功能。在Hibernate 的JTA 封裝中,Session.beginTransaction 同樣也執(zhí)行了InitialContext.lookup方法獲取UserTransaction實例,Transaction.commit方法同樣也調(diào)用了UserTransaction.commit方法。實際上,這就形成了兩個嵌套式的JTA Transaction:ClassC 申明了一個事務(wù),而在ClassC 事務(wù)周期內(nèi),ClassA 和ClassB也企圖申明自己的事務(wù),這將導致運行期錯誤。因此,如果決定采用JTA Transaction,應(yīng)避免再重復調(diào)用Hibernate 的
Transaction功能,上面的代碼修改如下:
Java代碼
[/url]
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代碼
[url=http://www.javaeye.com/topic/177988]

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();
……
}
}
實際上,這是利用Hibernate來完成啟動和提交UserTransaction的功能,但這樣的做法比原本直接通過InitialContext獲取UserTransaction 的做法消耗了更多的資源,得不償失。
在EJB 中使用JTA Transaction 無疑最為簡便,我們只需要將save 方法配置為JTA事務(wù)支持即可,無需顯式申明任何事務(wù),下面是一個Session Bean的save方法,它的事務(wù)屬性被申明為“Required”,EJB容器將自動維護此方法執(zhí)行過程中的事務(wù):
Java代碼
/**   
* @ejb.interface-method   
* view-type="remote"   
*   
* @ejb.transaction type = "Required"   
**/   
public void save(){   
//EJB環(huán)境中,通過部署配置即可實現(xiàn)事務(wù)申明,而無需顯式調(diào)用事務(wù)   
classA.save(user);   
classB.save(log);   
}//方法結(jié)束時,如果沒有異常發(fā)生,則事務(wù)由EJB容器自動提交。


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u2/65993/showart_2057131.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP