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

  免費(fèi)注冊 查看新帖 |

Chinaunix

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

Hibernate事務(wù)和并發(fā)控制 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-09-21 22:00 |只看該作者 |倒序?yàn)g覽
Hibernate對JDBC進(jìn)行了輕量級的對象封裝,Hibernate本身在設(shè)計(jì)時(shí)并不具備事務(wù)處理功能,平時(shí)所用的Hibernate的事務(wù),只是將底層的JDBCTransaction或者JTATransaction進(jìn)行了一下封裝,在外面套上Transaction和Session的外殼,其實(shí)底層都是通過委托底層的JDBC或JTA來實(shí)現(xiàn)事務(wù)的調(diào)度功能。
2.2.       Hibernate中使用JDBC事務(wù):
要在Hibernate中使用事務(wù),可以配置Hibernate事務(wù)為JDBCTransaction或者JTATransaction,這兩種事務(wù)的生命周期不一樣,可以在hibernate.cfg.xml中指定使用的是哪一種事務(wù)。以下配置為使用JDBC事務(wù)。注:如果不進(jìn)行配置,Hibernate也會(huì)默認(rèn)使用JDBC事務(wù)。
  

……

org.hibernate.transaction.JDBCTransactionFactory

……

Hibernate 使用JDBC transaction處理方式如下所示:
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();
}
2.3.       Hibernate中使用JTA事務(wù):
JTA(java Transaction API)是事務(wù)服務(wù)的JavaEE解決方案。本質(zhì)上,它是描述事務(wù)接口的JavaEE模型的一部分。
JTA具有的3個(gè)接口:UserTransaction接口、TransactionManager接口和Transaction接口,這些接口共享公共的事務(wù)操作。UserTransaction能夠執(zhí)行事務(wù)劃分和基本的事務(wù)操作,TransactionManager能夠執(zhí)行上下文管理。
在一個(gè)具有多個(gè)數(shù)據(jù)庫的系統(tǒng)中,可能一個(gè)程序?qū)?huì)調(diào)用幾個(gè)數(shù)據(jù)庫中的數(shù)據(jù),需要一種分布事務(wù),或者準(zhǔn)備用JTA來管理Session的長事務(wù),那么就需要使用JTATransaction。
在hibernate.cfg.xml中配置JTA事務(wù)管理:

……

org.hibernate.transaction.JTATransactionFactory

……

下面是一個(gè)實(shí)際應(yīng)用的JTA示例:
// BMT(bean管理事務(wù)) idiom with getCurrentSession()
try {
    UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");
  
    tx.begin();
  
    // Do some work on Session bound to transaction
    factory.getCurrentSession().load(...);
    factory.getCurrentSession().persist(...);
  
    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}
在CMT方式下,事務(wù)聲明是在session bean的部署描述符中,而不需要編程。 因此,代碼被簡化為:
// CMT idiom
Session sess = factory.getCurrentSession();
  
// do some work
...

3.    多個(gè)事務(wù)并發(fā)引起的問題:
3.1.        第一類丟失更新:撤消一個(gè)事務(wù)時(shí),把其它事務(wù)已提交的更新的數(shù)據(jù)覆蓋了。
3.2.        臟讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)未提交的更新數(shù)據(jù)。
3.3.        幻讀:一個(gè)事務(wù)執(zhí)行兩次查詢,但第二次查詢比第一次查詢多出了一些數(shù)據(jù)行。
3.4.        不可重復(fù)讀:一個(gè)事務(wù)兩次讀同一行數(shù)據(jù),可是這兩次讀到的數(shù)據(jù)不一樣。
3.5.        第二類丟失更新:這是不可重復(fù)讀中的特例,一個(gè)事務(wù)覆蓋另一個(gè)事務(wù)已提交的更新數(shù)據(jù)。
4.    事務(wù)隔離級別:
為了解決多個(gè)事務(wù)并發(fā)會(huì)引發(fā)的問題。數(shù)據(jù)庫系統(tǒng)提供了四種事務(wù)隔離級別供用戶選擇。
o Serializable:串行化。隔離級別最高
o Repeatable Read:可重復(fù)讀。
o Read Committed:讀已提交數(shù)據(jù)。
o Read Uncommitted:讀未提交數(shù)據(jù)。隔離級別最差。
數(shù)據(jù)庫系統(tǒng)采用不同的鎖類型來實(shí)現(xiàn)以上四種隔離級別,具體的實(shí)現(xiàn)過程對用戶是透明的。用戶應(yīng)該關(guān)心的是如何選擇合適的隔離級別。
對于多數(shù)應(yīng)用程序,可以優(yōu)先考慮把數(shù)據(jù)庫系統(tǒng)的隔離級別設(shè)為Read Committed,它能夠避免臟讀,而且具有較好的并發(fā)性能。
每個(gè)數(shù)據(jù)庫連接都有一個(gè)全局變量@@tx_isolation,表示當(dāng)前的事務(wù)隔離級別。JDBC數(shù)據(jù)庫連接使用數(shù)據(jù)庫系統(tǒng)默認(rèn)的隔離級別。在Hibernate的配置文件中可以顯示地設(shè)置隔離級別。每一種隔離級別對應(yīng)著一個(gè)正整數(shù)。
Read Uncommitted: 1
Read Committed: 2
Repeatable Read: 4
Serializable: 8
在hibernate.cfg.xml中設(shè)置隔離級別如下:
     

2

設(shè)置之后,在開始一個(gè)事務(wù)之前,Hibernate將為從連接池中獲得的JDBC連接設(shè)置級別。需要注意的是,在受管理環(huán)境中,如果Hibernate使用的數(shù)據(jù)庫連接來自于應(yīng)用服務(wù)器提供的數(shù)據(jù)源,Hibernate不會(huì)改變這些連接的事務(wù)隔離級別。在這種情況下,應(yīng)該通過修改應(yīng)用服務(wù)器的數(shù)據(jù)源配置來修改隔離級別。
5.    并發(fā)控制:
當(dāng)數(shù)據(jù)庫系統(tǒng)采用Red Committed隔離級別時(shí),會(huì)導(dǎo)致不可重復(fù)讀和第二類丟失更新的并發(fā)問題,在可能出現(xiàn)這種問題的場合?梢栽趹(yīng)用程序中采用悲觀鎖或樂觀鎖來避免這類問題。
5.1.       樂觀鎖(Optimistic Locking):
樂觀鎖假定當(dāng)前事務(wù)操縱數(shù)據(jù)資源時(shí),不會(huì)有其他事務(wù)同時(shí)訪問該數(shù)據(jù)資源,因此不作數(shù)據(jù)庫層次上的鎖定。為了維護(hù)正確的數(shù)據(jù),樂觀鎖使用應(yīng)用程序上的版本控制(由程序邏輯來實(shí)現(xiàn)的)來避免可能出現(xiàn)的并發(fā)問題。
唯一能夠同時(shí)保持高并發(fā)和高可伸縮性的方法就是使用帶版本化的樂觀并發(fā)控制。版本檢查使用版本號、 或者時(shí)間戳來檢測更新沖突(并且防止更新丟失)。
5.1.1.       使用版本檢查():
Hibernate中通過版本號檢查來實(shí)現(xiàn)后更新為主,這也是Hibernate推薦的方式。在數(shù)據(jù)庫表中加入一個(gè)version(版本)字段,在讀取數(shù)據(jù)時(shí)連同版本號一起讀取,并在更新數(shù)據(jù)時(shí)比較版本號與數(shù)據(jù)庫表中的版本號,如果等于數(shù)據(jù)庫表中的版本號則予以更新,并遞增版本號,如果小于數(shù)據(jù)庫表中的版本號就拋出異常。
使用進(jìn)行版本控制的步驟:
1)      在持久化類中定義一個(gè)代表版本號的屬性:
package org.qiujy.domain.versionchecking;
  
import java.util.Date;
  
public class Product implements java.io.Serializable{
       private Long id ;
       /** 版本號 */
       private int version;
       private String name; //產(chǎn)品名
       private String description; //描述--簡介
       private Double unitCost; //單價(jià)
       private Date pubTime; //生產(chǎn)日期
      
       public Product(){}
  
       //以下為getter()和setter()方法
}
2)      在Product.hbm.xml文件中用元素來建立Product類的version屬性與表中version字段的映射。
3)      Hibernate在其數(shù)據(jù)庫訪問引擎中內(nèi)置了樂觀鎖定實(shí)現(xiàn),默認(rèn)也是選擇version方式作為Hibernate樂觀鎖定實(shí)現(xiàn)機(jī)制。所以,在配置文件及程序中可以不作其它設(shè)置。按往常一樣寫操作代碼。
package org.qiujy.domain.versionchecking;
  
import java.util.Date;
  
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.qiujy.common.HibernateSessionFactory;
  
public class TestVersionChecking {
      
       public static void main(String[] args) {
              Product prod = new Product();
              prod.setName("IBM thinkPad T60");
              prod.setUnitCost(new Double(26000.00));
              prod.setDescription("筆記本電腦");
              prod.setPubTime(new Date());
              
              //test start.......
              Session session = HibernateSessionFactory.getSession();
              Transaction tx =null;
              try{
                     tx = session.beginTransaction();
                     
                     session.save(prod);
                
                    tx.commit();
              }catch(HibernateException e){
                     if(tx != null){
                            tx.rollback();
                     }
                     e.printStackTrace();
              }finally{
                     HibernateSessionFactory.closeSession();
              }
        
//進(jìn)行更新 測試..
              prod.setDescription("新款的");
              
              Session session2 = HibernateSessionFactory.getSession();
              Transaction tx2 =null;
              try{
                     tx2 = session2.beginTransaction();
                     
                     session2.update(prod);
               
                    tx2.commit();
              }catch(HibernateException e){
                     if(tx2 != null){
                            tx2.rollback();
                     }
                     e.printStackTrace();
              }finally{
                     HibernateSessionFactory.closeSession();
              }
       }
}
新增數(shù)據(jù)時(shí)產(chǎn)生的SQL是:
insert into products (version, name, description, unitCost, pubTime)
    values(?, ?, ?, ?, ?)
程序無需為Product對象的version屬性顯示賦值,當(dāng)持久化一個(gè)Product對象時(shí),Hibernate會(huì)自動(dòng)為它賦初始值為0。
更新數(shù)據(jù)時(shí)產(chǎn)生的SQL是:
    update
        products
    set
        version=?,
        name=?,
        description=?,
        unitCost=?,
        pubTime=?
    where
        id=?
        and version=?
當(dāng)Hibernate更新一個(gè)Product對象,會(huì)根據(jù)它的id和version屬性到相應(yīng)的數(shù)據(jù)庫表中定位匹配的記錄,如果存在這條匹配的記錄,就更新記錄,并且把version字段的值加1。若找不到匹配的記錄,此時(shí)Hibernate會(huì)拋出StaleObjectStateException。

需要注意的是,由于樂觀鎖定是使用系統(tǒng)中的程序來控制,而不是使用數(shù)據(jù)庫中的鎖定機(jī)制,因而如果有人故意自行更新版本信息來超過檢查,則鎖定機(jī)制就無效。所以建議把持久化類中的version的get方法設(shè)置為private的。
5.1.2.       使用時(shí)間戳():
跟版本檢查的用法相似。不再多說。
5.2.       悲觀鎖(Pessimistic Locking):
悲觀鎖假定當(dāng)前事務(wù)操縱數(shù)據(jù)資源時(shí),肯定還會(huì)有其他事務(wù)同時(shí)訪問該數(shù)據(jù)資源,為了避免當(dāng)前事務(wù)的操作受到干擾,先鎖定資源。盡管悲觀鎖能夠防止丟失更新和不可重復(fù)讀這類并發(fā)問題,但是它影響并發(fā)性能,因此應(yīng)該很謹(jǐn)慎地使用悲觀鎖。


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

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

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP