| Oracle | SQL Server | |
|---|---|---|
| 開始交易 | 無 | Begin Tran (Transaction) |
| 確定提交交易 | Commit | Commit Tran (Transaction) |
| 放棄還原交易 | Rollback | Rollback Tran (Transaction) |
BEGIN TRANSACTION:啟動交易。COMMIT TRANSACTION:如果沒有發生錯誤,可用來順利結束交易。ROLLBACK TRANSACTION:發生錯誤時,用來清除交易。交易所修改的一切資料都會回到交易啟動時的狀態。
ROLLBACK TRANSACTION會恢復還原到對應的BEGIN TRANSACTION執行前的狀態。
1
2
3
4
begin transaction
--1.DB操作:張三減少$1000
--2.DB操作:李四增加$2000
commit transaction
注意:執行
drop table語法之後,即使再執行rollback語法也將無法復原資料表。
(刪除資料表之後,對該資料表的索引也會同時被刪除)
範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
begin tran --開始交易
--進行判斷,不符合條件就還原異動前的狀態,不執行其他操作
if not exists(select ID from Product where ID = 14)
begin
rollback tran --放棄結束異動(=回到異動資料前的狀態)
return --跳出執行流程
end
--更新資料
update Product set ProductName='DVDROM' where ID = 14
--如果有錯誤就放棄結束異動,沒錯誤就提交
if(@@ERROR>0)
begin
rollback tran --恢復還原所有交易
end
commit tran --提交交易
範例:Rollback 錯誤的巢狀交易
在處理交易異動Transaction的時候,一般都用 RollBack Transaction放棄結束異動(=回到異動資料前的狀態),RollBack Transaction會恢復還原所有begin tran包括已經提交的異動和未提交的異動。
巢狀交易時,
ROLLBACK不管在哪一層,它會ROLLBACK巢狀中的所有交易
若是外部交易被
Rollback,則不管內部交易是否個別被Commit,所有的內部交易都會被Rollback。
1
2
3
4
5
6
begin tran
begin tran
update Product set ProductName = 'DVDROM-123' where ID = 14
commit tran --認可異動- 原本能夠成功更新的這段語法,會被後被ROLLBACK 給回復
update Product set ProductName = 'DVDROM-456' where ID = 13
rollback tran --會回復BEGIN TRANSACTION之後的所有異動,所以兩筆資料都不會被update
用
@@TRANCOUNT可以檢查是否已經打開一個交易異動Begin Tran。
SELECT @@TRANCOUNT结果是1,意思是目前連線已經開啟了一個交易異動Begin Tran。0的意思是目前沒有交易異動,一個大於1的數的意思是有巢狀交易。
@@TRANCOUNT的值是1,這個時候必須提交或回復交易,不然等到語句結束,表仍然是鎖住,會造成阻塞。
測試:重現錯誤
錯誤訊息:COMMIT TRANSACTION 要求沒有對應的 BEGIN TRANSACTION。
1
2
3
4
begin tran
select * from Test
rollback tran --對應上面的begin tran
commit tran --找不到匹配的交易聲明begin tran
說明:
交易的語法只能一一對應,只有一個開始交易的聲明begin tran,但卻有兩個交易操作,最後一個交易操作無法找到匹配的交易聲明,自然就會出錯。
MSDN - BEGIN TRANSACTION (Transact-SQL)
@@TRANCOUNT (檢視目前啟用 BEGIN TRAN 的數量)
Transactions
解决COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION错误