事務是什么?
是數據庫操作的最小工作單元,這些操作作為一個整體一起向系統提交,要么都執行、要么都不執行;事務是一組不可再分割的操作集合(工作邏輯單元);
事務的特性
(1)A(原子性):事務是一個工作單元,各個元素是不可分的。要么全部成功,要么全部失敗。
(2)C(一致性):事務是一個工作單元, 執行完成后,數據是正確的
(3)I(隔離性): 多個事務之間彼此隔離。
(4)D(持久性): 事務提交之后,對數據庫的更改是永久保存的,就算是系統出現故障,也會保留。
事務創建
--開啟事務 begin try begin tran --set implicit_transactions on --開啟一個隱式事務 --在這里做t-sql commit tran --提交事務 end try begin catch rollback tran --撤回事務 end catch --set implicit_transactions off --關閉隱式事務
事務並發問題
(1)臟讀(Dirty Read):一個事務讀取另外一個事務還沒有提交的數據叫臟讀(事務T1修改了一行數據,但是還沒有提交,這時候事務T2也讀取了這條數據,當T2要對這個數據進行增加或修改操作並提交的時候,T1事務回滾了,這個時候T2原先讀取的數據和數據庫現在的數據是不一樣的,那么事務T2讀取的數據就是臟的。)。
(2)不可重復讀(Unrepeatable Read):如果一個用戶在一個事務中多次讀取一條數據,而另外一個用戶則同時更新啦這條數據,造成第一個用戶多次讀取數據不一致。 (其他解釋:不可重復讀是指在同一個事務內,兩個相同的查詢返回了不同的結果。比如:事務T1讀取某一數據,事務T2讀取並修改了該數據,T1再次讀取該數據,便得到了不同的結果。)
(3)幻讀(Phantom Read):是指同一個事務內多次查詢返回的“數據條數”不一樣(比如增加了或者減少了行記錄)。比如同一個事務A內第一次查詢時候有n條記錄,但是第二次同等條件下查詢卻又n+1條 記錄,這就好像產生了幻覺,為啥兩次結果不一樣那。其實和不可重復讀一樣,發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集里面的數據。不同在於不可重復讀是同一個記錄的數據內容被修改了,幻讀是數據行記錄變多了或者少了。
(4)丟失或者覆蓋更新
事務a和b都對這個數據進行修改,可能a先修改,緊接着b又修改,造成了事務a的數據被覆蓋了,一個事務在不知道其他事務存在的情況下對數據進行修改,造成的數據丟失。
總結:
臟讀是指一個事務讀取到了其他事務沒有提交的數據,不可重復讀是指一個事務內多次根據同一個查詢條件查詢出來的“同一行記錄的值不一樣”,幻讀是指一個事務內多次 根據同個條件查出來的記錄行數不一樣。為了解決事務並發帶來的問題,才有了事務規范中的四個事務隔離級別,不同隔離級別對上面問題部分或者全部做了避免。
隔離級別
解決事務並發問題,可以設置事務隔離級別,隔離級別越低,並發問題越嚴重。
(1)read uncommited(未提交讀)
相當於沒有設置級別,都會產生。
(2)read commited(已提交讀)
這是數據庫默認的隔離級別,可以解決臟讀,但是會產生不可重復和幻讀。這個隔離級別規定只能讀取那些沒有被其它事務占用讀取的數據,所以能夠解決因事務回滾導致產生的臟讀(with(nolock)能破壞這個隔離級別)
(3)reapeatable read (可以重復讀),相當於(HOLDLOCK)
可以有效的避免臟讀,不可重復讀,但是會產生幻讀。
(4)serializebal(可序列化)
能夠解決臟讀,不可重復讀, 幻讀。
示例:
--開啟事務 begin try --設置隔離級別 可重復讀 set tran isolation level repeatable read begin tran --set implicit_transactions on --開啟一個隱式事務 --在這里做t-sql commit tran --提交事務 end try begin catch rollback tran --撤回事務 end catch --set implicit_transactions off --關閉隱式事務
as