posts - 262,  comments - 221,  trackbacks - 0

          一、數據并發帶來的各種情況 

          ①臟讀:事務A讀到事務B尚未提交的數據,并基于這個數據進行后續操作

          ②不可重復讀:事務A讀取數據后,被事務B修改或刪除,事務A再次讀取時前后兩次讀取的數據不一致

          ③幻像讀:事務A讀取數據后,事務B新增了數據,事務A再次讀取是前后兩次讀取的數據不一致


          不可重復讀和幻想讀的區別:

          幻象讀和不可重復讀是兩個容易混淆的概念,前者是指讀到了其它已經提交事務的新增數據,而后者是指讀到了已經提交事務的更改數據(更改或刪除),為了避免這兩種情況,采取的對策是不同的,防止讀取到更改數據,只需要對操作的數據添加行級鎖,阻止操作中的數據發生變化,而防止讀取到新增數據,則往往需要添加表級鎖——將整個表鎖定,防止新增數據(Oracle使用多版本數據的方式實現)。

          ④第一類更新丟失:事務A和事務B同時訪問同一個數據,事務B先提交修改,事務A回滾操作。導致事務B的修改丟失

          ⑤第二類更新丟失:事務A和事務B同時訪問同一個數據,事務B先提交修改,事務A再提交。導致事務B的修改被覆蓋

          第一類更新丟失是很嚴重的操作,如果控制不當,可能導致在一個長時間的大型事務中,所有的操作都被回滾。所以所有的數據庫都不支持這種并發情況。

          二、數據庫的鎖機制

          從鎖的作用范圍來分,可以分為:行級鎖和表級鎖
          從鎖的排他性來分,可以分為:共享鎖和獨占鎖(排他鎖),
          其中共享鎖允許共享,但阻止獨占鎖。獨占鎖不但不允許共享鎖,且不允許其它獨占鎖


          于是組合起來就有:

          ①行共享鎖:允許多個會話共享鎖定的行數據,但不允許對這些行的獨占鎖。例如select ...for update

          ②行獨占鎖:對行進行獨占,不允許其它的共享鎖(表,行)、獨占鎖(表,行)和表共享行獨占鎖。例如insert,update

          ③表共享鎖:允許多個會話共享表數據,但不允許其它的獨占鎖(表,行)、表共享行獨占鎖。可以實現表級事務一致性

          ④表獨占鎖:對表進行獨占,不允許其它的共享鎖(表,行)、讀占鎖(表,行)和表共享行獨占鎖。達到序列化操作級別

          ⑤表共享行獨占鎖:允許多個會話共享表數據,但同一時刻只能有一個行獨占鎖??梢赃_到數據共享同時防止臟讀、不可重復讀、幻像讀

          表共享鎖定可以讓會話具有對表事務級一致性訪問,因為其它會話在你提交或者回溯該事務并釋放對該表的鎖定之前不能更改這個被鎖定的表(因為要修改表的記錄,就必須獲得行獨占鎖,但是共享鎖會阻止獨占鎖的獲取,這樣原來其它正在讀取表記錄的事務就不會出現臟讀、不可重復讀、幻像讀的情況了);

          表共享行獨占鎖與其不同則是多了一個行獨占,這樣效率更高。

          三、事務隔離級別

          盡管數據庫為用戶提供了鎖的DML操作方式,但直接使用鎖管理是非常麻煩的,因此數據庫為用戶提供了自動鎖機制。只要用戶指定會話的事務隔離級別,數據庫就會分析事務中的SQL語句,然后自動為事務操作的數據資源添加上適合的鎖。此外數據庫還會維護這些鎖,當一個資源上的鎖數目太多時,自動進行鎖升級以提高系統的運行性能,而這一過程對用戶來說完全是透明的

          下面是ANSI ISO92定義的4個事務隔離級別以及對應的對數據并發的處理

          圖片

          READ COMMITITED:不允許讀取未提交的數據,但可以讀取已提交的數據。所以可能出現不可重復讀、和幻像讀(讀的過程依然可以被修改、增加、刪除)

           
          REPEATABLE READ:通過行鎖定,在讀的數據不允許其它進程修改。確保已讀取的數據不被修改、刪除(不可重復讀)但無法阻止其它進程寫入新數據,所以不能確保讀取到新的數據(幻像讀)
           
          SERIALIZABLE:通過表鎖定,徹底禁止讀取期間其它進程的修改、刪除(屏蔽不可重復讀)和增加(屏蔽幻像讀)
           
          但是不管是那種隔離級別,對第一類丟失更新都是不能接收的 


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2010-03-15 11:04 Paul Lin 閱讀(1079) 評論(0)  編輯  收藏 所屬分類: J2EE 框架
          <2010年3月>
          28123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 凤城市| 皋兰县| 五峰| 烟台市| 江孜县| 宿迁市| 富阳市| 廉江市| 漾濞| 郴州市| 呼玛县| 新兴县| 卢龙县| 林州市| 尉犁县| 清水河县| 黎川县| 宁津县| 邵阳市| 昂仁县| 彭阳县| 天水市| 阿合奇县| 桓仁| 三穗县| 宁德市| 宜章县| 正定县| 稷山县| 从江县| 黄冈市| 神池县| 威远县| 牙克石市| 绥化市| 永善县| 临西县| 雷州市| 习水县| 东城区| 永年县|