引發思考 今天,發現開發項目中的單號重覆了。 這是多用戶併發操作相同數據導致的結果。有點抽象,理解如下:實際就是多個事務交叉執行(增、刪、查、改)了相同數據。導致一個事務不具有完整性了,資料庫的數據也不一致了(這裡‘’一致‘’可以理解為:我希望的數據,跟我想像的不一樣,比如明明我剛update某表性 ...
引發思考
今天,發現開發項目中的單號重覆了。
這是多用戶併發操作相同數據導致的結果。有點抽象,理解如下:實際就是多個事務交叉執行(增、刪、查、改)了相同數據。導致一個事務不具有完整性了,資料庫的數據也不一致了(這裡‘’一致‘’可以理解為:我希望的數據,跟我想像的不一樣,比如明明我剛update某表性別為男,我update完它還是女的,如果別人要修改,也得等我update完再改呀!咦,統計男生的總人數的確是加1了,見鬼了)。
併發操作數據的不利影響
多個用戶試圖修改其他用戶正在使用的資源時總是會產生負面影響。(這裡用戶可以理解成事務,用戶這個片語總是在不同場合出現,例如redis客戶端用戶,b/s模式客戶端用戶,這些情況其實可以廣泛理解為請求)
更新丟失:A事務里更新某些數據,A還沒結束運行。這段時間,B插足一腳,也更新了那些數據,覆蓋了A剛更新完的,A白更了。一段時間後,A正常結束了,A丟失了更新的數據。
臟讀:B正在修改某些數據,還沒結束運行。這段時間A去讀那些數據,但讀的不是B修改之後的,而是B修改之前的。一段時間後,B正常結束了,A讀的數據還是舊數據。
不可重覆讀:9點鐘,A在讀某部分數據。9點半,B修改了那部分數據,B結束運行了。10點鐘,A又回頭讀那部分數據,發現數據和9點鐘的不一樣。A讀的是同一部分,卻返回不一樣的數據。
幻讀:9點鐘A根據條件取了一個結果集看看,還沒結束運行。9點半,B刪除了那個結果集部分行數據,又新增了部分行數據。10點,A根據相同條件取結果集,發現新增了部分,刪除了部分,剛剛是在做夢吧?
總而言之,一旦小三插足幹壞事,我就完了。
事務鎖
針對上面的問題,可以使用事務鎖解決。(事務鎖是一種悲觀的解決方案,)
每個事務里可能涉及行數據、頁數據、表數據、,這數據相等事務依賴的資源,當請求操作這些資源,可以請求不同類型的鎖。 該鎖可以阻止其他事務以錯誤方式操作該資源。 當事務不再依賴鎖定的資源時,它將釋放鎖。
簡單說,這些數據可以被上鎖、上鎖後,其他事務對該數據的操做就有限制了,不是你想改就能改,你想讀就讀。我鎖是大爺,我允許,你就能操作;我若不許,你就滾出去!
鎖粒度: SQL Server具有多種粒度鎖定,例如行粒度、表粒度、資料庫粒度......
如果在較小的粒度(例如行)加鎖,可以提高併發度,因為對其他事務限制範圍小,只是開銷較高,鎖定了多少行,則需要多少鎖。
比如A事務拿到了某行數據的某鎖,該限制了其他事務對該行數據的操作,但是其他事務不一定要操作該行,也是就1兩個事務需要操作改行,
如果在較大的粒度(例如表)加鎖,則會降低併發度,因為鎖定整個表限制了其他事務對錶中任意部分的訪問。 但開銷較低,因為需要維護的鎖較少。
鎖類型:共用鎖、排他鎖等。鎖與鎖之間是可以衝突的。比如A事務拿到了某行數據的共用鎖,說明A事務結束之前,該行數據都不能被其他事務修改(增、刪、改),但是其他事務可以讀改行數據。其他事務永遠都不能拿到該行數據的排他鎖,排他鎖的作用是獨自占據數據的增、刪、改操作。
這篇文章不過拋轉引玉罷了,官方的就很齊全了 https://docs.microsoft.com/zh-cn/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-2017