我接觸.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語句再更新,看一下失敗的情況
use test
drop table bank
create table bank
(
bid char(4) primary key,
balance money check(balance>=50)
)
insert into bank values('001','1000');
insert into bank values('002','100');
--此時轉帳就違反了約束必須大於10塊錢,所以第一條會執行失敗,但是第二條會執行成功
update bank set balance=balance-1000 where bid='001';
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語句創建事務,避免上面那種情況
DECLARE @sumError int
set @sumError=0
BEGIN TRANSACTION
update bank set balance=balance-1000 where bid='001';
set @sumError = @sumError +@@Error
update bank set balance=balance+1000 where bid='002';
set @sumError = @sumError +@@Error
IF(@sumError = 0)
BEGIN
COMMIT TRANSACTION
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
--通過上面的事務代碼,兩條代碼要麼同時執行成功,要麼同時執行失敗