離線并發的來源

         Web項目中,離線并發顯得尤其嚴重。例如,用戶A和用戶B同時修改數據庫中的某張表的R行,加入R行有兩個字段分別是C1C2

         假如按照如下過程修改:

         1 用戶A將數據RC1,C2)讀取到A的瀏覽器中。

         2 用戶B將數據RC1,C2)讀取到B的瀏覽器中。

         3 用戶A在瀏覽器上將數據修改為RC1’C2),同時更新到數據庫。

         4 用戶B在瀏覽器上將數據修改為RC1C2’),同時更新到數據庫。

        

         上述過程存在兩個問題,第一,第4B在修改數據的時候數據庫中的數據和B的瀏覽器中數據已經不一致了;第二,如果程序按照哪個字段變化在數據庫中更新哪個字段的方式處理的話,那么經過上述四步修改,數據庫中R行的內容是(C1’,C2’),這和A或者B的想法都不同(A認為是(C1’C2),B認為是(C1C2’))。

 

         上述過程中A對數據庫的修改過程或者B對數據庫的修改過程,都是無法根據數據庫的最新內容做修改,所以成為離線。AB同時對記錄R進行就該叫離線。

 

         以上的環境叫離線并發。

 

         那么如何解決離線并發過程中遇到的問題呢?我們引入鎖機制。

        

鎖機制

         鎖機制,就是在需要修改的數據上加互斥鎖,通過互斥鎖避免數據被同時修改。鎖機制更具其應用環境又分為樂觀鎖悲觀鎖

 

         樂觀鎖

樂觀鎖,指認為沖突很少發生,所以只是在數據修改的時候比較修改的基礎數據和數據庫中的數據是否相同,相同則修改,否則提示用戶重新裝入數據庫中已經變化的數據。

實現方法1:在進行update的時候使用where條件,在Where標間中比較所有上一步中查詢得到的數據。如果數據庫中的數據沒有變化,則update可以更新到內容,否則update語句不能更新到內容,可以根據update的返回值確定更新是否成功。

實現方法2:在每一個表中追加一個特殊字段,類型為timestamp,每次更新的時候比較這個字段的值是否一致,如果一致,則更新,同時將這個字段更新為當前時間,否則,說明數據已經變更。這也可以使用update加上where實現。

 

         悲觀鎖

悲觀鎖指,需要修改的數據,在讀取的時候就對數據加鎖,其他用戶在準備修改,讀取數據的階段判斷數據是否上鎖,以此來決定是否進行修改前的讀操作。

        

                  實現方法:

                   通常在數據庫中建立一張lock表,該表的字段包括,表明,唯一索引,時間,用戶信息等。

        

在用戶讀取數據準備修改的時候,首先判斷lock表中是否存在自己將要讀取的數據。

如果不存在,則在lock表中添加一條記錄,記錄對那張表的哪行數據進行修改;如果存在,在判斷時間字段是否超時。

如果超時,則更新lock表中本條記錄的時間字段。(防止死鎖的必要手段)

如果存在,也不超時,說明本條記錄正在被其他用戶修改,則返回并發信息。



ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程