滿店香的家

          學習+實踐=進步

          JDBC的隔離級別研究 (轉(zhuǎn))

           

          原創(chuàng) JDBC的隔離級別研究

           在通過JDBC對數(shù)據(jù)庫進行并發(fā)訪問時,為了解決并發(fā)之間的鎖的控制,JDBC提供了一個隔離級別(Isolation)的方式解決并發(fā)訪問的問題。
              因為最近時間在解決公司工作流在客戶現(xiàn)場的高并發(fā)情況下經(jīng)常出現(xiàn)死鎖(dead lock)或者事務(wù)超時情況,而工作流的應(yīng)用大多數(shù)主要這幾種業(yè)務(wù):查詢工作項、領(lǐng)取工作、完成(或者提交)工作。根據(jù)以前公司在其他應(yīng)用中并沒有出現(xiàn)這 些故障,對所上線的環(huán)境進行的分析,主要差異是出問題的系統(tǒng)是DB2(其他系統(tǒng)基本上是ORACLE)。針對上面的問題進行了下面分析。
           
          數(shù)據(jù)庫的差異性:
          • ORACLE數(shù)據(jù)庫比較強調(diào)能夠支持高并發(fā)情況下的訪問,保證能夠“讀”到數(shù)據(jù)
          • DB2數(shù)據(jù)庫比較強調(diào)高并發(fā)情況下的數(shù)據(jù)完整性,保證能夠“讀一致”的數(shù)據(jù)
          數(shù)據(jù)庫的隔離級別分析:
          • ORACLE缺省使用的是CS級別的數(shù)據(jù)庫訪問
          • DB2缺省使用的是RS級別的數(shù)據(jù)庫訪問
          JDBC的數(shù)據(jù)隔離級別設(shè)置:
           
          JDBC
          數(shù)據(jù)庫隔離級別
          數(shù)據(jù)訪問情況
          TRANSACTION_READ_UNCOMMITTED
          ur
          就是俗稱“臟讀”(dirty read),在沒有提交數(shù)據(jù)時能夠讀到已經(jīng)更新的數(shù)據(jù)
          TRANSACTION_READ_COMMITTED
          cs
          在一個事務(wù)中進行查詢時,允許讀取提交前的數(shù)據(jù),數(shù)據(jù)提交后,當前查詢就可以讀取到數(shù)據(jù)。update數(shù)據(jù)時候并不鎖住表
          TRANSACTION_REPEATABLE_READ
          rs
          在一個事務(wù)中進行查詢時,不允許讀取其他事務(wù)update的數(shù)據(jù),允許讀取到其他事務(wù)提交的新增數(shù)據(jù)
          TRANSACTION_SERIALIZABLE
          rr
          在一個事務(wù)中進行查詢時,不允許任何對這個查詢表的數(shù)據(jù)修改。
           
          在websphere環(huán)境中通過JDBC連接DB2數(shù)據(jù)庫的隔離級別的情況:
          • 只有使用實體(Entity Bean)的情況下可以通過修改ibm的部署文件修改當前數(shù)據(jù)操作的隔離級別
          • 如果通過session bean,jdbc connection方式獲得的數(shù)據(jù)庫連接缺省都是TRANSACTION_REPEATABLE_READ
          • 在通過數(shù)據(jù)源獲得DB2的數(shù)據(jù)庫連接時候,DB2的JDBC driver會缺省修改當前連接的隔離級別到TRANSACTION_REPEATABLE_READ
          工作流應(yīng)用分析:
           
              在工作流應(yīng)用中,主要是這些操作:查詢工作項、領(lǐng)取工作、完成(或者提交)工作。
          • 查詢工作項,數(shù)據(jù)庫操作是select,在工作流應(yīng)用中的操作頻率最高
          • 領(lǐng)取工作,數(shù)據(jù)庫操作是update,在工作流應(yīng)用中的操作頻率較低
          • 完成(或者提交)工作,數(shù)據(jù)庫操作主要是update、insert,在工作流應(yīng)用中的操作頻率較低
              根據(jù)上面的應(yīng)用分析,工作流應(yīng)用中大量的select,少量對數(shù)據(jù)進行update,而發(fā)生死鎖(dead lock)的現(xiàn)象是在DB2,在ORACLE上基本沒有發(fā)生的主要原因是:
           
              在DB2中數(shù)據(jù)庫的隔離級別是rs,如果系統(tǒng)中有大量的select,特別是如果查詢的工作項特別多,查詢慢的情況下,造成其他的update操作等待select請求結(jié)束,如果又有大量的select請求過來時會出現(xiàn)死鎖(dead lock)
           
          解決方案:
           
              首先考慮參照ORACLE的模式,將DB2的JDBC連接的隔離級別改為TRANSACTION_READ_COMMITTED,來提高并發(fā)能力,通常情況下獲取數(shù)據(jù)庫連接都是通過一個方法獲得,因此可以直接改這個方法獲得連接后直接將JDBC的Connection的隔離級別調(diào)整為TRANSACTION_READ_COMMITTED。但是在驗證這種方案是發(fā)現(xiàn)了一個問題:
              如果在一個JTA事務(wù)中,先獲取一個JDBC的Connection,程序修改了隔離級別到TRANSACTION_READ_COMMITTED, 在這個Connection中進行了數(shù)據(jù)庫操作,然后關(guān)閉連接,再從數(shù)據(jù)源中獲取Connection時候,DB2的Driver會修改當前的連接的隔離 級別,造成了在一個全局事務(wù)中修改了隔離級別,系統(tǒng)會自動拋出異常。
           
              上面的方案中是對任何一個Connection都修改隔離級別,因為存在問題,因此只能對單個數(shù) 據(jù)庫請求進行隔離級別的操作。對所有的獲取工作項的select查詢語句之后添加上 with cs的方式,這樣這條查詢請求并不會鎖住表,其他update操作就能夠正常工作。

          posted on 2008-05-12 02:51 滿店香 閱讀(599) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 抚顺县| 大化| 迁西县| 邻水| 遂溪县| 彭水| 分宜县| 惠水县| 临江市| 邛崃市| 游戏| 阳曲县| 孟津县| 恩平市| 海丰县| 陆川县| 钟祥市| 三明市| 隆尧县| 河北区| 个旧市| 惠州市| 靖州| 布拖县| 姜堰市| 克拉玛依市| 徐汇区| 都匀市| 潞城市| 汤阴县| 台中市| 江山市| 绥阳县| 衡水市| 宁波市| 横峰县| 当阳市| 衡南县| 邵武市| 尤溪县| 林甸县|