標籤:sql語句 導致 區別 分割 幻讀 行鎖 允許 讀取 約束
資料庫鎖:資料庫鎖出現的原因是為了處理並發問題。
並發控制一般採用三種方法,分別是樂觀鎖和悲觀鎖以及時間戳記。
樂觀鎖認為一個使用者讀資料的時候,別人不會去寫自己所讀的資料,就是不做任何操作。悲觀鎖就剛好相反,覺得自己讀資料庫的時候,別人可能剛好在寫自己剛讀的資料,其實就是持一種比較保守的態度,悲觀鎖就是在讀取資料的時候,為了不讓別人修改自己讀取的資料,就會先對自己讀取的資料加鎖,只有自己把資料讀完了,才允許別人修改那部分資料,或者反過來說,就是自己修改某條資料的時候,不允許別人讀取該資料,只有等自己的整個事務提交了,才釋放自己加上的鎖,才允許其他使用者訪問那部分資料。悲觀鎖所說的加“鎖”。
悲觀鎖分為:
讀鎖/共用鎖定:共用的鎖,多個用戶端可以同時讀取一個資源,互補幹擾。
寫鎖/排它鎖:一個鎖會阻塞其他的寫鎖和讀鎖,確保一個時刻只有一個用戶端對通過一個資料進行修改寫入。
時間戳記就是在資料庫表中單獨加一列時間戳記,比如“TimeStamp”,每次讀出來的時候,把該欄位也讀出來,當寫回去的時候,把該欄位加1,提交之前 ,跟資料庫的該欄位比較一次,如果比資料庫的值大的話,就允許儲存,否則不允許儲存。
表鎖 是開銷比較小的策略,會鎖定整張表。MyISAM和InnoDB都支援表級鎖定。使用者對錶進行寫操作,需要先獲得鎖,並且會阻塞使用者對該表的所有讀操作。 資料庫中對錶進行修改,如alter table會使用到表鎖,會鎖定整張表,因此此類操作在資料庫中應該謹慎使用。
行鎖 行鎖可以高效的支援並發,當然鎖開銷也是最大。MySQL的InnoDB引擎中實現了行鎖,在使用者寫資料時,只鎖定需要操作的資料行,相比於表鎖並發度更好。
InnoDB支援事務,
事務是資料庫區別於檔案系統的額重要特性之一。事務符合ACID特性。原子性:原子性是指資料庫事務是不可分割的工作單位。只有資料庫事務中的所有資料庫操作執行都成功,才算整個事務成功。如果事務中的任何一個SQL語句執行失敗,已經執行的SQL語句也必須撤銷,資料庫狀態退回到執行事務前的狀態。
一致性:事務執行之前和之後,資料庫的完整性條件約束沒有被破壞。
隔離性:一個事物的影響在它提交前對其他事務不可見(通過鎖來實現)
持久性:事務一旦提交,其結果就是永久性的。
原子性,一致性,持久性通過redo,undo來完成。
並發事務所帶來的問題:
- 更新丟失(Lost Update):當兩個事務T1和T2讀入同一資料做修改並發執行時,T2把T1或T1把T2的修改結果覆蓋掉,造成資料的丟失更新問題,導致資料的不一致。
- 髒讀(Dirty Reads):事務T1更新了資料R,事務T2讀取了更新後的資料R,事務T1由於某種原因被撤銷,恢複資料R。這樣T2讀取的資料和資料庫中內容不一樣。
- 不可重複讀取(Non-Repeatable Reads):一個事務對同一行資料讀取了兩次,結果不同。
- (1)事務T1讀取了資料R,事務T2讀取並更新了R,當事務再讀取R進行核對時,兩次讀取的值不一樣。
- (2)事務操作過程中進行了兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的資料或缺少了第一次查詢的資料,這種情況稱為幻讀。
間隙鎖(Next-Key鎖) 當我們用範圍條件而不是相等條件檢索資料,並請求共用或獨佔鎖定時,InnoDB會給合格已有資料的索引項目加鎖;對於索引值在條件範圍內但並不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制不是所謂的間隙鎖(Next-Key鎖)。 舉例來說,假如emp表中只有101條記錄,其empid的值分別是1,2,...,100,101,下面的SQL:
SELECT * FROM emp WHERE empid > 100 FOR UPDATE 是一個範圍條件的檢索,InnoDB不僅會對合格empid值為101的記錄加鎖,也會對empid大於101(這些記錄並不存在)的“間隙”加鎖。 InnoDB使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關隔離等級的要求,對於上面的例子,要是不使用間隙鎖,如果其他事務插入了empid大於100的任何記錄,那麼本事務如果再次執行上述語句,就會發生幻讀;另一方面,是為了滿足其恢複和複製的需要。有關其恢複和複製對機制的影響,以及不同隔離等級下InnoDB使用間隙鎖的情況。 很顯然,在使用範圍條件檢索並鎖定記錄時,InnoDB這種加鎖機制會阻塞符合條件範圍內索引值的並發插入,這往往會造成嚴重的鎖等待。因此,在實際開發中,尤其是並發插入比較多的應用,我們要盡量最佳化商務邏輯,盡量使用相等條件來訪問更新資料,避免使用範圍條件。死結
兩個使用者分別鎖定一個資源,之後雙方又都等待雙方釋放所鎖定資源,就產生一個鎖定請求環,從而出現死結。死結往往出現在行級鎖中。
如何解決死結?
在InnoDB的交易管理和鎖定機制中,有專門用於檢測死結的機制。當檢測當死結時,InnoDB會選擇產生死結的兩個事務中的較小的一個完成復原。
mysql中的鎖的相關知識