1. 程式人生 > >數據庫的事物隔離級別以及鎖的一些個人理解

數據庫的事物隔離級別以及鎖的一些個人理解

nco 理解 rep 查詢 釋放 如果 就是 時間 server

數據庫的 基本分為 共享鎖和排它鎖

排它鎖顧名思義,不能和其他任何所共存。

以SqlServer中某一行數據為例,

特殊的,WithNoLock 這個是不給數據加上任何鎖,所以根本和鎖沒關系

再說update,update的過程是給這條數據加上排它鎖,所以當另外事物過來要求修改這條數據的時候,會由於排它鎖的互斥,導致無法申請到排它鎖,從而實現同一時間只有一個事物對同一條數據進行修改。同樣當該條數據正在修改中但其所屬的事物還未提交的時候,查詢需要在這條數據上加上共享鎖的過程也由於排它鎖的存在導致被阻塞。只有當修改的操作完成並且其所在事物提交以後,其他需要在該數據上加鎖的操作才能進行下去。

最後說 select ,一般的select 是直接給數據加上一個共享鎖,其他的事物中的select 由於這條數據將是存在共享鎖的原因,所以可以在多個事物中查詢同一條數據。

說到鎖自然要提到數據庫事物隔離級別

各種隔離級別就是通過鎖來實現,

以sqlserver為例,

read uncommited

直接可以當作WithNoLock 理解了

read commited

事物1 select該數據時加上共享鎖,讀完該共享鎖立即釋放。此時事物2中的update操作可以正常給該條數據加上排它鎖並執行,若此時事物1再次select 該數據會發現該數據已經改變(由於事物2已經改變了該數據) ,這也就是所謂的臟讀。所以 read commited 有臟讀的風險。

repeatable read

事物1 select該數據時加上共享鎖,但是直到事物完成該共享鎖才釋放,所以在事物1執行過程中,事物2過來想要update該條數據,都由於update需要加上排它鎖,而和事物1的共享鎖沖突,導致update被阻塞。這就避免了臟讀的問題。但是如果事物2僅僅是select 且 事物1 沒有update,那麽是可以被讀取的。且如果事物2新增一條數據。那麽事物1的select 有可能讀到的數據比原來多。這種情況被稱為幻讀,所以 repeatable read 有幻讀的風險。

serializable

為了解決幻讀的情況,把整個表都鎖住,在事物1執行的時候,事物2連新增刪除都不允許。

再說說delete 首先update 的過程其實是先新增再刪除,這點可以從觸發器中看出來。所以update是獨占鎖也就是說明了delete 也是獨占鎖。所以delete 的情況可以當作update 來理解。

數據庫的事物隔離級別以及鎖的一些個人理解