顯式事務與隱式事務
事務相關方法
DbTransaction 或 IDbContextTransaction
Commit 和 Rollback
context.Database.XXX
BeginTransaction、BeginTransactionAsync、CommitTransaction、CurrentTransaction、 RollbackTransaction 和UseTransaction方法。
if (!context.Blogs.Any(b => b.Url.Length > 10)) { context.Database.RollbackTransaction(); }
四種隔離級別
01:Read uncommitted(讀未提交):最低級別,任何情況都會發生。
02:Read Committed(讀已提交):可避免臟讀的發生。
03:Repeatable read(可重復讀):可避免臟讀、不可重復讀的發生。
04:Serializable(串行化):避免臟讀、不可重復讀,幻讀的發生。
注: 四種隔離級別:Seralizable 級別最高,最低的是 Read uncommitted 級別,級別越高,執行效率就越低,隔離級別的設置只對當前鏈接有效,對.NET 操作數據庫來說,一個 Connection 對象相當於一個鏈接。
01:MySQL 數據庫的默認隔離級別是Repeatable read 級別。
02:Oracle數據庫中,只支持 Seralizable 和 Read committed級別,默認的是 Read committed 級別。
03:SQL Server 數據庫中,默認的是Read committed 級別。
四種隔離級別場景舉例
01: Read uncommitted 讀未提交, 公司發工資了,領導把 5000 元打到老斷的賬號上,但是該事務並未提交,而老斷正好去查看賬戶,發現工資已經到賬,是 5000 元整,非常高興。可是不幸的是,領導發現發給老斷的工資金額不對,應該
是 2000 元,於是迅速回滾了事務,修改金額為 2000 后,將事務提交,最后老斷實際的工資只有 2000 元,老斷空歡喜
一場,場面十分尷尬,假如老段是神速,在事務回滾前取走了 5000 元,事情就更加難辦了,還得去公司財務退錢。
02:Read committed 讀已提交, 老斷拿着工資卡去買衣服,系統讀取到卡里確實有 2000 元,而此時他的媳婦也正好在網上轉賬,把老斷工資卡的 2000 元轉到另一賬戶,並在老斷完成付款之前提交了事務,當老斷扣款時,系統檢查到老斷的工資卡已經沒有錢,扣款失敗,老斷十分納悶,就短短幾毫秒,明明卡里有錢,怎么突然就沒錢了,思考了半天,尷尬離場。
03:Repeatable read 重復讀,當老斷拿着工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),老斷的媳婦就不可能對該記錄進行修改,也就是老斷的媳婦不能在此時轉賬。
04:重復讀可能出現幻讀: 老斷的媳婦工作在銀行部門,她時常通過銀行內部系統查看老斷的信用卡消費記錄。有一天,她正在查詢到老斷當月信用卡的總消費金額為 80 元,而老斷此時正好吃完火鍋在收銀台買單,消費 1000 元,即新增了一條 1000 元的消費記錄,並提交了事務,老斷的媳婦准備回家問問老斷這 80 元是干啥花掉的,於是乎她將老斷當月信用卡消費的明細打印到 A4 紙上,卻發現消費總額為 1080 元,老斷的老婆很詫異,剛剛查出來不是 80 元嘛,以為出現了幻覺,幻讀就這樣產生了。
Serializabale:最高的事務隔離級別,代價花費最高,性能很低,很少使用,在此級別下,事務順序執行,以避免上述所 有產生的情況。
來自<https://www.cnblogs.com/phpfeng/p/9333829.html>
數據庫事務死鎖
活動與監視器
使用數據庫視圖
sys.dm_tran_locks
向鎖管理器發出的已授予鎖或正等待授予鎖的每個當前活動請求分別對應一行。
結果集中的列大體分為兩組:資源組和請求組。 資源組說明正在進行鎖請求的資源,請求組說明鎖請求。
SQL Server Profiler
通過系統健康狀況
KILL
結束基於會話 ID 的用戶進程, 如果指定的會話 ID 有許多工作要撤消,KILL 語句可能需要一段時間才能完成,特別是在進程涉及回滾長事務時,此過程可能需要更長的時間才能完成。
https://docs.microsoft.com/zh-cn/sql/t-sql/language-elements/kill-transact-sql
sp_who
提供有關當前用戶、 會話和進程的實例中的信息Microsoft SQL Server 數據庫引擎。 可以篩選信息以便只返回那些屬於特定用戶或特定會話的非空閑進程。