死鎖:mysql
指兩個事務或者多個事務在同一資源上相互佔用,並請求對方所佔用的資源,從而形成惡性循環的現象。 sql
出現死鎖的緣由: 數據庫
系統資源不足;
進程運行推動的順序不當;
資源分配不當。 併發
產生死鎖的四個必要條件:
互斥條件: 一個資源只能被一個進程使用;
請求和保持條件:進行得到必定資源,又對其餘資源發起了請求,可是其餘資源被其餘線程佔用,請求阻塞,可是也不會釋放本身佔用的資源;
不可剝奪條件: 指進程所得到的資源,不可能被其餘進程剝奪,只能本身釋放;
環路等待條件: 進程發生死鎖,必然存在着進程-資源之間的環形鏈。.net
數據庫也會發生死鎖的現象,數據庫系統實現了各類死鎖檢測和死鎖超時機制來解除死鎖,鎖監視器進行死鎖檢測,MySQL的InnoDB處理死鎖的方式是將持有最少行級排它鎖的事務進行回滾。線程
常見的三種避免死鎖的方法:版本控制
若是不一樣程序會併發存取多個表,儘可能約定以相同的順序訪問表,能夠大大下降死鎖機會;對象
在同一個事務中,儘量作到一次鎖定所須要的全部資源,減小死鎖產生機率;blog
對於很是容易產生死鎖的業務部分,能夠嘗試使用升級鎖定顆粒度,經過表級鎖定來減小死鎖產生的機率。進程
樂觀鎖和悲觀鎖都是爲了解決併發控制問題, 樂觀鎖能夠認爲是一種在最後提交的時候檢測衝突的手段,而悲觀鎖則是一種避免衝突的手段。
樂觀鎖:
樂觀鎖應用系統層面和數據的業務邏輯層次上的(實際上並無加鎖,只不過你們一直這樣叫而已),利用程序處理併發, 它假定當某一個用戶去讀取某一個數據的時候,其餘的用戶不會來訪問修改這個數據,可是在最後進行事務的提交的時候會進行版本的檢查,以判斷在該用戶的操做過程當中,沒有其餘用戶修改了這個數據。
樂觀鎖不是數據庫自帶的,須要咱們本身去實現。樂觀鎖的實現大部分都是基於版本控制實現的,級別高低是:髒讀 < 不可重複讀 < 幻讀(級別介紹詳細見數據庫的事務隔離級別)。 除此以外,還能夠經過時間戳的方式,經過提早讀取,過後對比的方式實現。
悲觀鎖:
每次拿數據的時候都認爲別的線程會修改數據,因此在每次拿的時候都會給數據上鎖。上鎖以後,當別的線程想要拿數據時,就會阻塞,直到給數據上鎖的線程將事務提交或者回滾。傳統的關係型數據庫裏就用到了不少這種鎖機制,好比行鎖,表鎖,共享鎖,排他鎖等,都是在作操做以前先上鎖。與樂觀鎖相對應的,悲觀鎖是由數據庫本身實現,要用的時候,咱們直接調用數據庫的相關語句就能夠。
共享鎖和排它鎖是悲觀鎖的不一樣的實現,它倆都屬於悲觀鎖的範疇。
共享鎖:
共享鎖又稱爲讀鎖,簡稱S鎖,共享鎖就是多個事務對於同一數據能夠共享一把鎖,都能訪問到數據,可是隻能讀不能修改。
好比事務T對數據對象A加上S鎖,則事務T只能讀A;其餘事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這就保證了其餘事務能夠讀A,但在T釋放A上的S鎖以前不能對A作任何修改。
排他鎖:
排他鎖又稱爲寫鎖,簡稱X鎖,排他鎖就是不能與其餘所並存,如一個事務獲取了一個數據行的排他鎖,其餘事務就不能再獲取該行的其餘鎖,包括共享鎖和排他鎖,可是獲取排他鎖的事務是能夠對數據就行讀取和修改。
好比事物T對數據對象A加上X鎖,則只容許T讀取和修改A,其它任何事務都不能再對A加任何類型的鎖,直到T釋放A上的鎖。它防止任何其它事務獲取資源上的鎖,直到在事務的末尾將資源上的原始鎖釋放爲止。
注意:
mysql InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,若是加排他鎖可使用select ...for update語句,加共享鎖可使用select ... lock in share mode語句。因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select ...from...查詢數據,由於普通查詢沒有任何鎖機制。--------------------- 做者:一騎走煙塵 來源:CSDN 原文:https://blog.csdn.net/zgcr654321/article/details/82345087 版權聲明:本文爲博主原創文章,轉載請附上博文連接!