悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。 經過 jdbc 實現時 sql 語句只要在整個語句以後加 for update 便可。例如: select …for updatesql
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量,像數據庫若是提供相似於write_condition機制的其實都是提供的樂觀鎖。數據庫
兩種鎖各有優缺點,不可認爲一種好於另外一種,像樂觀鎖適用於寫比較少的狀況下,即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是常常產生衝突,上層應用會不斷的進行retry,這樣反卻是下降了性能,因此這種狀況下用悲觀鎖就比較合適併發
在第一個鏈接中執行如下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個鏈接中執行如下語句
begin tran
select * from table1
where B='b2'
commit tran
若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒性能
互斥鎖(Mutex)this
互斥鎖是一個互斥的同步對象,意味着同一時間有且僅有一個線程能夠獲取它。spa
互斥鎖可適用於一個共享資源每次只能被一個線程訪問的狀況線程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace MyTTCon { class shareRes { public static int count = 0; public static Mutex mutex = new Mutex(); } class IncThread { int number; public Thread thrd; public IncThread(string name, int n) { thrd = new Thread(this.run); number = n; thrd.Name = name; thrd.Start(); } void run() { Console.WriteLine(thrd.Name + "正在等待 the mutex"); //申請 shareRes.mutex.WaitOne(); Console.WriteLine(thrd.Name + "申請到 the mutex"); do { Thread.Sleep(1000); shareRes.count++; Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count); number--; } while (number > 0); Console.WriteLine(thrd.Name + "釋放 the nmutex"); // 釋放 shareRes.mutex.ReleaseMutex(); } } class DecThread { int number; public Thread thrd; public DecThread(string name, int n) { thrd = new Thread(this.run); number = n; thrd.Name = name; thrd.Start(); } void run() { Console.WriteLine(thrd.Name + "正在等待 the mutex"); //申請 shareRes.mutex.WaitOne(); Console.WriteLine(thrd.Name + "申請到 the mutex"); do { Thread.Sleep(1000); shareRes.count--; Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count); number--; } while (number > 0); Console.WriteLine(thrd.Name + "釋放 the nmutex"); // 釋放 shareRes.mutex.ReleaseMutex(); } } class Program { static void Main(string[] args) { IncThread mthrd1 = new IncThread("IncThread thread ", 5); DecThread mthrd2 = new DecThread("DecThread thread ", 5); mthrd1.thrd.Join(); mthrd2.thrd.Join(); } } }
小結:code
悲觀鎖:查詢加鎖 【select ...... for update】對象
樂觀鎖:修改加鎖 【版本號控制】blog
排它鎖:事務A能夠查詢、修改,直到事務A釋放爲止才能夠執行下一個事務
共享鎖:事務A能夠查詢、修改,同時事務B也能夠查詢但不能修改
互斥鎖:同一資源同一時間只能被一個線程訪問