iT邦幫忙

3

關於SQL Transaction

Han 2019-03-19 18:08:252102 瀏覽

原文:

先就我對Transaction的理解描述一下

通常這用在需同時更動多個資料
為確保都有更動到,而使用的功能!

如果其中有一個SQL執行錯誤則rollback
反之則commit

疑問的點是:

如果沒有commit那資料庫就不會真的變動
那為何需要rollback??

那如果真的有變動到,rollback就是要還原變動
那幹嘛commit...

第一次發問~希望感受一下大家的熱情XD


更新問題及理解狀況

看了大家的回應以及回答

我可以理解為
不commit直接結束有可能造成table被lock住
如果kill proccess的話
沒有commit的transaction會自動rollback

一個transcaction的開始
必定伴隨著commitrollback當結尾

縱使沒有commit可以自動rollback
但這個方法非正規,也不穩定。


不過我以一個例子來講好了
我現在的感覺是
下SQL就像在用記事本的功能
我打開一個記事本 並做各種修改
但在這之後我覺得做錯了
我要重來 我可以直接關掉記事本不存檔不是嗎

雖然拿記事本跟DB比好像不太對
但目前 我是這樣看DB的...
希望各位大大給我觀念糾正一下((汗


更新狀況

因為目前工作比較偏向於下SQL的
不是管理的
那平常都使用php去下指令

最近是看前人的code才接觸rollback以及commit
因此多有不解

看code會執行差不多10條SQL
都在update不同table
確認真的所有table都update成功才commit
其中一個失敗或是有exception便rollback

完全可以理解邏輯

直接講個實例好了

在php內 開始transaction
下了幾次SQL指令 有update資料或insert資料
commitrollback 直接sleep一分鐘

問題
1.其他proccess去select在transaction中變動的資料 會是變動前還是後?
2.使用command直接kill正在sleep的proccess 是會自動rollback嗎?

其實這兩個問題好像自己實驗就可以了
但我的問題是這個結論之後的事
我猜測 1.前 2.是
這個情況下
既然transaction沒結束就不會變動到資料
為何需要擔心資料亂掉而影響其他人??
我自己在出錯的時候直接結束程式就好了 反正會自動rollback

PPTaiwan iT邦新手 5 級 ‧ 2019-03-20 14:17:11 檢舉
你直接 Po 你寫 transaction 的方式,用 SQL SSMS 來寫一個來看看...
fysh711426 iT邦研究生 3 級 ‧ 2019-03-21 08:56:52 檢舉
> 1.其他 proccess 去 select 在 transaction 中變動的資料 會是變動前還是後?

要看其他 proccess 怎麼去 select,如果下 nolock 就可以查到未 commit 的資料,而正常情況下因為 update 的資料會使用獨佔鎖,所以其他 proccess 會被鎖住,必需等待交易完成後才能查詢資料。

> 2.使用 command 直接 kill 正在 sleep 的 proccess 是會自動rollback嗎?

會,未 commit 的資料,連線中斷或資料庫當機,都會自動 rollback,這樣才能確保資料是正確可靠的。
Han iT邦新手 5 級 ‧ 2019-03-25 09:38:13 檢舉
了解 感謝各位大大的回覆 已經了解transaction的重要性~
0
PPTaiwan
iT邦新手 5 級 ‧ 2019-03-20 11:40:45
最佳解答

問你喔 ...你一個 Transaction 裡面做了多少 insert、update、Delete 混合使用呢??

用 Transaction 是一種良好的習慣,你在對資料庫做任何運算或是因為專案的需求來做 insert、update、Delete 那你如何確保你的語法沒有問題呢?? 或是你的 Table 因為修改而使得己經寫過的 程式 發生了失敗呢?? 失敗了,那你不做 Transaction 而使的資料內可能混亂掉那你如何處理??

可能因為你寫錯而使得 Table lock ,如果你的公司有 DBA 那你會被罵死!! 如果你公司沒有 DBA 那你寫的專案品質都要再三考慮了,真的...

"如果沒有commit那資料庫就不會真的變動" 這句話被 DBA 知道,那你會被再三教育!!

Han iT邦新手 5 級 ‧ 2019-03-20 12:30:59 檢舉

更新了問題點 煩請大大撥空看一下/images/emoticon/emoticon22.gif

1
淺水員
iT邦新手 2 級 ‧ 2019-03-19 20:55:29

在命令列中使用資料庫
分別開兩個視窗做測試
如果沒有執行 commit 或是 rollback
那麼資料會持續處於鎖定狀態
造成其他使用者必須繼續等待

至於網頁後端(我知道的是PHP)
則是在連線結束後會自動 rollback
(不確定是自動 rollback 還是伴隨著與資料庫連線中斷產生)

看更多先前的回應...收起先前的回應...
Han iT邦新手 5 級 ‧ 2019-03-19 23:02:58 檢舉

那這樣在撰寫上(php)

是否在SQL指令出現錯誤時
可以直接exit
沒有rollback也不是什麼大問題吧??

這問題一直困惑著我XD

圓頭人 iT邦新手 2 級 ‧ 2019-03-20 08:42:28 檢舉

實驗一下,就知道了

sam0407 iT邦高手 1 級 ‧ 2019-03-20 10:02:11 檢舉

直接exit,Transaction不會結束,異動的資料就還是Lock狀態,那其他人就要等到Transaction Timeout後才能存取這些資料

fysh711426 iT邦研究生 3 級 ‧ 2019-03-20 10:09:24 檢舉

可以用 kill 測試
結果是連線中斷會自動將未 commit 的資料 rollback

Han iT邦新手 5 級 ‧ 2019-03-20 12:30:47 檢舉

更新了問題點 煩請各位大大撥空看一下/images/emoticon/emoticon22.gif

淺水員 iT邦新手 2 級 ‧ 2019-03-20 14:42:52 檢舉

我自己是寫一個 function 來處理需要使用 transaction 的一系列 SQL 命令,如果中間失敗會 function 自動執行 rollback 。這樣就不用擔心忘記下 rollback 了。

0
rogeryao
iT邦高手 7 級 ‧ 2019-03-20 14:56:58

若有 2 條(含)以上的 SQL 指令要同時做 table 異動(新增,修改,刪除),為確保資料異動一致性,因此使用 Transaction 方式運作.

當執行 SQL 指令時 :
1.若指令皆正確,則執行 commit 完成異動 => 相關 table 資料被更新
2.若指令有任何一條錯誤,則執行 rollback 取消異動 => 相關 table 資料維持原狀

未使用 Transaction 方式運作,若發生"指令有任何一條錯誤"時,
就會導致資料異動不一致,將會造成資料的正確性有問題(兩個報表查到的數據不一樣)

請用 SQL Server Profiler 去瞭解 Transaction 的運作

我要發表回答

立即登入回答