高并发与锁(二)
上文我們介紹了高并發(fā)狀態(tài)下會產(chǎn)生的一些數(shù)據(jù)沖突和鎖的一些基本分類,這次我們繼續(xù)討論。
? ? 如何添加樂觀鎖? 在高并發(fā)情況下,如何高效、健康地給select 語句加上行鎖?SQL Server是如何控制并發(fā)沖突的?
? ? 1、添加樂觀鎖
? ??在J2EE中,Hirbernate提供了悲觀所和樂觀鎖,但悲觀鎖的使用同樣也限制了讀取的并發(fā)性,因此很少使用,二使用最多的是添加樂觀鎖,在記錄中添加版本version或者時間戳字段,這樣做并不影響讀取,只是按照版本控制的思維來限制低版本記錄修改操作。
? ? 對于以上兩種方式,hibernate自帶實現(xiàn)方式:在使用樂觀鎖的字段前加annotation: @Version, Hibernate在更新時自動校驗該字段。
? ? 那么有人要問,低版本記錄有新的數(shù)據(jù),怎么才能更新?
? ? 其實也很簡單:開啟事務->更新記錄前,讀取一次最新的數(shù)據(jù)->提交->回滾或者提交事務。
? ? 又該如何保持version和timestamp呢,在提交的過程中,只需將version或者timestramp進行更新即可。
? ? 2、在高并發(fā)情況下,如何高效、健康地給select 語句加上行鎖?
? ??高并發(fā)情況下,簡單地添加行鎖,數(shù)據(jù)庫可能會支持不住,可以:
? ? (1)對請求做個隊列,先進先出,不會重復,但是速度上會不會變慢?
? ? (2)避免實時讀取數(shù)據(jù)庫,把數(shù)據(jù)緩存起來;數(shù)據(jù)用隊列裝起來,讀走就沒了。也可以單獨啟用一個線程,采用異步方式實現(xiàn);
? ? (3)環(huán)境中有Redis的話直接使用自帶的隊列接口就行,按一定順序裝進去,取得時候是原子操作,取完就沒有了。
? ? 3、SQL Server是如何控制并發(fā)沖突的?
? ??悲觀與樂觀機制下,數(shù)據(jù)庫設定了隔離級別:
? ? SQL Server2005及以上版本支持5種隔離級別來控制沖突。其中三種只在悲觀并發(fā)模式中使用,一種只在樂觀并發(fā)模式中使用,另一個可以在兩種模式中使用。
? ?(1)未提交讀(Uncommitted Read)
? ? 未提交讀只能防止“丟失更新”問題,其它問題不能防止。
? ? 未提交讀是針對阻塞太頻繁的悲觀并發(fā)控制,因為它只是忽略了鎖,而不保障事務的一致性。
? ?(2)已提交讀(Read Committed)
? ? 已提交讀既可以是樂觀的也可以是悲觀的,這取決于數(shù)據(jù) 庫的read_committed_snapshot設置。默認情況下這個 選項是關閉的,所以該隔離級別默認情況下是采用悲觀并發(fā)控制。
? ? 已提交讀可以防止臟讀問題。
? ?(3)可重復讀(Repeatable Read)
? ? 可重復讀是一種悲觀的隔離級別。它在已提交讀的基礎上增加了新特性:確保當事務重新訪問數(shù)據(jù)或查詢被再一次執(zhí)行時,數(shù)據(jù)將不會再發(fā)生改變。
? ? 可重復讀不但可以防止臟讀問題,還可以防止不可重復讀問題,但是不能防止幻讀問題。
? ? 注意,可重復讀的資源開銷是很大的,事務中所有的數(shù)據(jù)必須等待事務完成之后才能訪問。
? ?(4)快照(Snapshot)
? ? 快照是一種樂觀隔離級別。
? ? Snapshot事務中任何語句所讀取的記錄,都是事務啟動時的數(shù)據(jù)。
? ? 這相當于事務啟動時,數(shù)據(jù)庫為事務生成了一份專用“快照”。
? ? 在當前事務中看到不其它事務在當前事務啟動之后所進行的數(shù)據(jù)修改。
? ? Snapshot事務不會讀取記錄時要求鎖定,讀取記錄的Snapshot事務不會鎖住其它事務寫入記錄,寫入記錄的事務也不會鎖住Snapshot事務讀取數(shù)據(jù)。
? ? 快照隔離級別的事務不是串行執(zhí)行的,兩個進程同時使用快照隔離,如果它們執(zhí)行多次,可能最終產(chǎn)生的結果不會一致。(這段話要證實)
? ?(5)可串行化(Serializable)
? ? 可串行化是一種悲觀隔離級別。它在可重復讀的基礎上增加了新的特性:確保在兩次查詢的中間,不會增加新的行。
? ? 可串行化是最健壯的悲觀隔離級別,因為它防止了并發(fā)沖突產(chǎn)生的4個問題。
? ? 可串行化也是資源開銷最大的措施。當使用可串行化隔離時,如果SQL的條件字段沒有索引,那么SQL Server會產(chǎn)生表級鎖。
總結
- 上一篇: 高并发与锁
- 下一篇: 自己开的公司怎么记账