我接觸.NET編程已經有兩年了,在這之前就會一點ASP和SQL語句。剛接觸時在網上請教一個從事ASP.NET工作不久的網友,什么是事務? 當時他沒答上。事實上我接觸.NET這兩年里,做一些小例子,也不用到事務。所以我對事務是什么?為什么要有事務?還是這幾天才清楚。在理解什么是事務前,先來考慮這么一個問題。
為什么要有事務?
假設我們在進行銀行轉帳的時候,至少會執行兩條SQL語句,一條SQL語句是減少轉帳人里帳戶的錢,一條是增加收帳人里帳戶錢。 例如有一個朋友要轉帳1000元:1、那么轉帳人的銀行里的錢減少1000
2、那么收帳人的銀行里的錢增加1000
我們往深一點想,在執行這兩條SQL語句的時候,會不會發生問題?會,有時候天災,人禍的。例如。在執行第一條SQL語句的時候,就在這0.001秒之間機器突然出現故障,那么這時候有可能第二條SQL語句沒有執行。那這時候轉帳人不就很慘,他自己轉帳了1000元,自己帳戶已經扣了錢,可是對方的帳戶沒收到錢,那么對方會很生氣的認為你沒有給他轉帳。
這還是兩條SQL語句出現問題的情況,試想如果銀行在處理事務時有100條SQL語句要執行,每條都很重要,那么出現問題的概率不是更大了嗎?為了針對這種情況出現了事務。
那么什么是事務?
事物是指訪問並可能更新數據庫中各種新據項的一個程序執行單行(UNIT),也就是由多個SQL語句組成,必需作為一個整體執行。 事物說白了一點,就是同生共死,意思要么全部的SQL語句都執行成功,要么全部的SQL語句都執行失敗。所以為了防止上面那種情況,要么兩條SQL語句都執行成功,要么兩條SQL語句都執行失敗。
通過例子來了解一下事務,在舉個例子前先看一下,先看幾個事務常用到的詞
- 開始事務:BEGIN TRANSACTION
- 事務提交:CIMMIT TRANSACTION
- 事務回滾: ROLL BACK TRANSACTION
- 查看語句有沒有錯誤: @@ERROR
當沒有發生錯誤的時候便可以將事務進行提交(CIMMIT TRANSACTION),而查看有沒有SQL語句的執行錯誤,可以用 @@ERROR來進行查看。當發生錯誤的時候便使用(ROLL BACK TRANSACTION)將SQL語句回滾到最最之前,沒有執行SQL語句那時候。
先來通過表后插入兩條SQL語句再更新,看一下失敗的情況
代碼如下:

1 use test 2 drop table bank 3 create table bank 4 ( 5 bid char(4) primary key, 6 balance money check(balance>=50) 7 ) 8 9 insert into bank values('001','1000'); 10 insert into bank values('002','100'); 11 12 --此時轉帳就違反了約束必須大於10塊錢,所以第一條會執行失敗,但是第二條會執行成功 13 update bank set balance=balance-1000 where bid='001'; 14 update bank set balance=balance+1000 where bid='002';
--消息 547,級別 16,狀態 0,第 1 行
--UPDATE 語句與 CHECK 約束"CK__bank__balance__0519C6AF"沖突。該沖突發生於數據庫"test",表"dbo.bank", column 'balance'。
--語句已終止。
--(1 行受影響)
select * from bank
bid balance
001 1000.00
002 1100.00
查看結果發現 002的值增加了1000,但是001的值並沒有變為0。
如何用SQL語句創建事務,避免上面那種情況

1 DECLARE @sumError int 2 set @sumError=0 3 BEGIN TRANSACTION 4 update bank set balance=balance-1000 where bid='001'; 5 set @sumError = @sumError +@@Error 6 update bank set balance=balance+1000 where bid='002'; 7 set @sumError = @sumError +@@Error 8 9 IF(@sumError = 0) 10 BEGIN 11 COMMIT TRANSACTION 12 END 13 ELSE 14 BEGIN 15 ROLLBACK TRANSACTION 16 END
--通過上面的事務代碼,兩條代碼要么同時執行成功,要么同時執行失敗