posts - 167,  comments - 30,  trackbacks - 0

          軟件系統的并發控制一般是通過加鎖(有樂觀鎖和悲觀鎖兩種)來實現,樂觀鎖是一種事后補救措施,是通過程序的邏輯控制版本來實現的,而悲觀鎖是事前的一種預防措施,它利用數據庫的鎖機制來實現。

          雖然樂觀鎖能夠提高系統的性能,但它是對發生沖突的訪問進行事后的補救,應用在用戶輸入數據量很少的場合比較適合,但如果在企業ERP,用戶與系統交互涉及大量數據在頁面表單上錄入,如果事后提交失敗后才提示用戶要重新錄入是很不現實的,所以有必要進行事前控制,這就要采用悲觀鎖。

          在多個客戶端可能讀取同一筆數據或同時更新一筆數據的情況下,防止同一個數據被修改而造成混亂,最簡單的手段就是在讀取時對數據進行鎖定,其它客戶端不能對同一筆數據進行更新的讀取動作。

          一個典型的倚賴數據庫的悲觀鎖調用:
          select * from account where name=”John” for update

          這條 sql 語句鎖定了 account 表中所有符合檢索條件(name=”Erica”)的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。Hibernate 的悲觀鎖,也是基于數據庫的鎖機制實現。
          下面的代碼實現了對查詢記錄的加鎖:
          String hqlStr ="from TUser as user where user.name='John'";
          Query query = session.createQuery(hqlStr);
          query.setLockMode("user",LockMode.UPGRADE); // 加鎖
          List userList = query.list();// 執行查詢,獲取數據

          query.setLockMode 對查詢語句中,特定別名所對應的記錄進行加鎖(我們為TUser 類指定了一個別名 “user” ),這里也就是對返回的所有 user 記錄進行加鎖。
          觀察運行期 Hibernate 生成的 SQL 語句:
          select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
          as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
          from t_user tuser0_ where (tuser0_.name='John' ) for update

          這里 Hibernate 通過使用數據庫的 for update 子句實現了悲觀鎖機制。
          Hibernate 的加鎖模式有:
          LockMode.NONE : 無鎖機制。
          LockMode.WRITE : Hibernate 在 Insert 和 Update 記錄的時候會自動獲取。
          LockMode.READ : Hibernate 在讀取記錄的時候會自動獲取。
          以上這三種鎖機制一般由 Hibernate 內部使用,如 Hibernate 為了保證 Update過程中對象不會被外界修改,會在 save 方法實現中自動為目標對象加上 WRITE 鎖。
          LockMode.UPGRADE :利用數據庫的 for update 子句加鎖。
          LockMode. UPGRADE_NOWAIT : Oracle 的特定實現,利用 Oracle 的 for update nowait 子句實現加鎖。
          上面這兩種鎖機制是我們在應用層較為常用的,加鎖一般通過以下方法實現:
          Criteria.setLockMode
          Query.setLockMode
          Session.lock

          注意,只有在查詢開始之前(也就是 Hiberate 生成 SQL 之前)設定加鎖,才會真正通過數據庫的鎖機制進行加鎖處理,否則,數據已經通過不包含 for update 子句的 Select SQL 加載進來,所謂數據庫加鎖也就無從談起。

          posted on 2011-03-17 16:03 David1228 閱讀(496) 評論(0)  編輯  收藏 所屬分類: Hibernate/ibatis

          <2011年3月>
          272812345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          文章檔案

          新聞分類

          新聞檔案

          相冊

          收藏夾

          Java

          Linux知識相關

          Spring相關

          云計算/Linux/虛擬化技術/

          友情博客

          多線程并發編程

          開源技術

          持久層技術相關

          搜索

          •  

          積分與排名

          • 積分 - 358881
          • 排名 - 154

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 广南县| 怀柔区| 松江区| 大同市| 岑溪市| 凭祥市| 德钦县| 福泉市| 巨鹿县| 黔东| 腾冲县| 南雄市| 句容市| 阿克陶县| 波密县| 舟山市| 辽宁省| 新化县| 牡丹江市| 平顺县| 华容县| 明溪县| 崇信县| 临沭县| 道孚县| 邮箱| 宝应县| 从化市| 建水县| 周至县| 山阴县| 梅河口市| 新乡市| 阳朔县| 梧州市| 湖南省| 洛阳市| 建宁县| 和平区| 徐闻县| 莱芜市|