建了一個USER資料表,包含ID與金額欄位
撰寫一個簡單的TRANSACTION,更新ID=3的USER金額
Transaction有正常begin與commit,所以再次select時,資料正確。
再來我故意將commit拿掉,此時Transaction執行後將無法結束(也就是TABLE會被LOCK)
從參數 @@TRANCOUNT知道此TRAN已經執行了(一次),但因為沒有commit,資料都還沒真的寫入。
這時候在回頭執行SELECT時,會撈不出資料
但是!
如果此時加入 WITH (NOLOCK),就可以撈出來了!!
可以看到值也已經更改,因為UPDATE有執行到 (請記得資料還沒COMMIT)
這時候回頭加入rollback,再執行一次transaction,
資料會復原,TABLE也會解除LOCK
此時一般的SELECT就可以執行了,不會再TIMEOUT
而數值會恢復到執行前的狀態(因為資料rollback了)
所以如果某個系統程序執行了一段冗長耗時的TRANSACTION
所有相關的TABLE在執行期間都會LOCK,此時某人要撈資料就必須下WITH (NOLOCK)
以上例子:
- 金額amount會在Transaction內異動,不適合搭配NOLOCK撈取。
- ID或姓名name,可使用NOLOCK,避免Transaction執行間無法撈取。
附帶一提,如果剛好要撈的資料欄位必須等TRANSACTION結束(不能用NOLOCK),
又不想讓USER看到逾時的話,可以改用NOWAIT判斷,然後提示USER,如下:
關於 NOWAIT 的實作範例可 參考這裡