離線并發(fā)的來源
????????
在
Web
項目中,離線并發(fā)顯得尤其嚴重。例如,用戶
A
和用戶
B
同時修改數(shù)據(jù)庫中的某張表的
R
行,加入
R
行有兩個字段分別是
C1
,
C2
。
????????
假如按照如下過程修改:
???????? 1
用戶
A
將數(shù)據(jù)
R
(
C1,C2
)讀取到
A
的瀏覽器中。
???????? 2
用戶
B
將數(shù)據(jù)
R
(
C1,C2
)讀取到
B
的瀏覽器中。
???????? 3
用戶
A
在瀏覽器上將數(shù)據(jù)修改為
R
(
C1’
,
C2
),同時更新到數(shù)據(jù)庫。
???????? 4
用戶
B
在瀏覽器上將數(shù)據(jù)修改為
R
(
C1
,
C2’
),同時更新到數(shù)據(jù)庫。
????????
????????
上述過程存在兩個問題,第一,第
4
步
B
在修改數(shù)據(jù)的時候數(shù)據(jù)庫中的數(shù)據(jù)和
B
的瀏覽器中數(shù)據(jù)已經(jīng)不一致了;第二,如果程序按照哪個字段變化在數(shù)據(jù)庫中更新哪個字段的方式處理的話,那么經(jīng)過上述四步修改,數(shù)據(jù)庫中
R
行的內(nèi)容是(
C1’,C2’
),這和
A
或者
B
的想法都不同(
A
認為是(
C1’
,
C2
),
B
認為是(
C1
,
C2’
))。
?
????????
上述過程中
A
對數(shù)據(jù)庫的修改過程或者
B
對數(shù)據(jù)庫的修改過程,都是無法根據(jù)數(shù)據(jù)庫的最新內(nèi)容做修改,所以成為離線。
A
和
B
同時對記錄
R
進行就該叫離線。
????????
以上的環(huán)境叫離線并發(fā)。
????????
那么如何解決離線并發(fā)過程中遇到的問題呢?我們引入鎖機制。
鎖機制
????????
鎖機制,就是在需要修改的數(shù)據(jù)上加互斥鎖,通過互斥鎖避免數(shù)據(jù)被同時修改。鎖機制更具其應(yīng)用環(huán)境又分為樂觀鎖和悲觀鎖
????????
樂觀鎖
樂觀鎖,指認為沖突很少發(fā)生,所以只是在數(shù)據(jù)修改的時候比較修改的基礎(chǔ)數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)是否相同,相同則修改,否則提示用戶重新裝入數(shù)據(jù)庫中已經(jīng)變化的數(shù)據(jù)。
實現(xiàn)方法
1
:在進行
update
的時候使用
where
條件,在
Where
標間中比較所有上一步中查詢得到的數(shù)據(jù)。如果數(shù)據(jù)庫中的數(shù)據(jù)沒有變化,則
update
可以更新到內(nèi)容,否則
update
語句不能更新到內(nèi)容,可以根據(jù)
update
的返回值確定更新是否成功。
實現(xiàn)方法
2
:在每一個表中追加一個特殊字段,類型為
timestamp
,每次更新的時候比較這個字段的值是否一致,如果一致,則更新,同時將這個字段更新為當前時間,否則,說明數(shù)據(jù)已經(jīng)變更。這也可以使用
update
加上
where
實現(xiàn)。
????????
悲觀鎖
悲觀鎖指,需要修改的數(shù)據(jù),在讀取的時候就對數(shù)據(jù)加鎖,其他用戶在準備修改,讀取數(shù)據(jù)的階段判斷數(shù)據(jù)是否上鎖,以此來決定是否進行修改前的讀操作。
????????
????????
實現(xiàn)方法:
??????????????????
通常在數(shù)據(jù)庫中建立一張
lock
表,該表的字段包括,表明,唯一索引,時間,用戶信息等。
在用戶讀取數(shù)據(jù)準備修改的時候,首先判斷
lock
表中是否存在自己將要讀取的數(shù)據(jù)。
如果不存在,則在
lock
表中添加一條記錄,記錄對那張表的哪行數(shù)據(jù)進行修改;如果存在,在判斷時間字段是否超時。
如果超時,則更新
lock
表中本條記錄的時間字段。(防止死鎖的必要手段)
如果存在,也不超時,說明本條記錄正在被其他用戶修改,則返回并發(fā)信息。
出處:http://blog.csdn.net/struts2/archive/2007/08/14/1742686.aspx