問(wèn)題背景及特點(diǎn):
我們在使用多用戶(hù)數據庫時(shí)常常會(huì )碰到數據更新失敗、刪除失等情況,如果有多個(gè)用戶(hù)且同時(shí)訪(fǎng)問(wèn)一個(gè)數據庫則當他們的事務(wù)同時(shí)使用相同的數據時(shí)可能會(huì )發(fā)生并發(fā)問(wèn)題。
并發(fā)問(wèn)題包括:
1.丟失或覆蓋更新。(幻像讀)
2.未確認的相關(guān)性(臟讀)。
3.不一致的分析(非重復讀)。
詳細描述:
1.丟失更新
當兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行時(shí),會(huì )發(fā)生丟失更新問(wèn)題。每個(gè)事務(wù)都不知道其它事務(wù)的存在。最后的更新將重寫(xiě)由其它事務(wù)所做的更新,這將導致數據丟失。
例如,兩個(gè)編輯人員制作了同一文檔的電子復本。每個(gè)編輯人員獨立地更改其復本,然后保存更改后的復本,這樣就覆蓋了原始文檔。最后保存其更改復本的編輯人員覆蓋了第一個(gè)編輯人員所做的更改。如果在第一個(gè)編輯人員完成之后第二個(gè)編輯人員才能進(jìn)行更改,則可以避免該問(wèn)題。
2.未確認的相關(guān)性(臟讀)
當第二個(gè)事務(wù)選擇其它事務(wù)正在更新的行時(shí),會(huì )發(fā)生未確認的相關(guān)性問(wèn)題。第二個(gè)事務(wù)正在讀取的數據還沒(méi)有確認并且可能由更新此行的事務(wù)所更改。
例如,一個(gè)編輯人員正在更改電子文檔。在更改過(guò)程中,另一個(gè)編輯人員復制了該文檔(該復本包含到目前為止所做的全部更改)并將其分發(fā)給預期的用戶(hù)。此后,第一個(gè)編輯人員認為目前所做的更改是錯誤的,于是刪除了所做的編輯并保存了文檔。分發(fā)給用戶(hù)的文檔包含不再存在的編輯內容,并且這些編輯內容應認為從未存在過(guò)。如果在第一個(gè)編輯人員確定最終更改前任何人都不能讀取更改的文檔,則可以避免該問(wèn)題。
3.不一致的分析(非重復讀)
當第二個(gè)事務(wù)多次訪(fǎng)問(wèn)同一行而且每次讀取不同的數據時(shí),會(huì )發(fā)生不一致的分析問(wèn)題。不一致的分析與未確認的相關(guān)性類(lèi)似,因為其它事務(wù)也是正在更改第二個(gè)事務(wù)正在讀取的數據。然而,在不一致的分析中,第二個(gè)事務(wù)讀取的數據是由已進(jìn)行了更改的事務(wù)提交的。而且,不一致的分析涉及多次(兩次或更多)讀取同一行,而且每次信息都由其它事務(wù)更改;因而該行被非重復讀取。
例如,一個(gè)編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫(xiě)了該文檔。當編輯人員第二次讀取文檔時(shí),文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫(xiě)后編輯人員才可以讀取文檔,則可以避免該問(wèn)題。
4.幻像讀
當對某行執行插入或刪除操作,而該行屬于某個(gè)事務(wù)正在讀取的行的范圍時(shí),會(huì )發(fā)生幻像讀問(wèn)題。事務(wù)第一次讀的行范圍顯示出其中一行已不復存在于第二次讀或后續讀中,因為該行已被其它事務(wù)刪除。同樣,由于其它事務(wù)的插入操作,事務(wù)的第二次或后續讀顯示有一行已不存在于原始讀中。
例如,一個(gè)編輯人員更改作者提交的文檔,但當生產(chǎn)部門(mén)將其更改內容合并到該文檔的主復本時(shí),發(fā)現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產(chǎn)部門(mén)完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問(wèn)題。
--------------------------------------------------------------------------------------------------------
從上面可以看到,解決并發(fā)主要是用到了鎖和事務(wù)。
鎖 :給記錄或表加上鎖是為了對當前操作對象加上一個(gè)狀態(tài)表示位,
讓其它用戶(hù)在獲取編輯權限時(shí)有了判斷。
事務(wù):是為了保證一組操作的完整性。(要么就全部成功,要么就全部失敗)
--------------------------------------------------------------------------------------------------------
一般處理并發(fā)問(wèn)題時(shí)我這樣做:
1.開(kāi)啟事務(wù)。
2.申請寫(xiě)權限,也就是給對象(表或記錄)加鎖。
3.如果失敗,則結束事務(wù),過(guò)一會(huì )重試。
4.如果成功,也就是給對象加鎖成功,防止其它用戶(hù)再用同樣的方式打開(kāi)。
5.進(jìn)行編輯操作。
6.寫(xiě)入所進(jìn)行的編輯結果。
7.如果寫(xiě)入成功,則提交事務(wù),完成操作。
8.如果寫(xiě)入失敗,則回滾事務(wù),取消提交。
9.(7.8)兩步操作已釋放了鎖定的對象,恢復到操作前的狀態(tài)。

