一、有時候我們需要同時執行很多個SQL操作,但是這些要執行的SQL有一部分執行成功了,比如原本應該向幾個相互關聯的表中插入數據,但是只有其中一個表的數據插入成功了,這時按照正常的邏輯,只要插入其中一個表失敗了,那么就應該撤銷已經成功了插入操作,這樣事務就派上用場了。
二、事務的特性
1、原子性 事務是一個完整的操作,事務的各操作時不可分的,要么都執行,要么都不執行。
2、一致性 當事務完成時,數據必須處於一致狀態
3、隔離性 並發事務之間彼此隔離,獨立,它不應該以任何方式依賴與或影響其他事務。
4、永久性 事務完成后,它對數據庫的修改會永久行的保存。、
三、事務的三個步驟
開啟事務
BEGIN TRANSACTION
這里是要執行的SQL腳本
if 判斷SQL腳本是否產生錯誤
如果執行SQL腳本沒有出錯,那么就執行
COMMIT TRANSACTION
else
如果執行SQL腳本出錯,那么就回滾事務
ROLLBACK TRANSACTION
具體代碼如下:
DECLARE @errorSum int --定義變量,用於累計事務執行中的錯誤 set @errorSum = 0; --0代表無錯誤 --開啟事務 begin transaction begin --SQL操作 --如果SQL語句發生錯誤,那么就讓錯誤變量++ set @errorSum = @errorSum + @@ERROR;--@@ERROR 是一個全局變量,只要發生執行SQL語句錯誤時,@@ERROR就會自動+1 if(@errorSum>0) --有錯誤就回滾事務 rollback transaction else --沒有錯誤就提交事務 commit transaction end go
三、事務的應用(在SQLserver中事務通常會結合存儲過程一起使用)
這里舉一個簡單的例子:如圖是一個簡單的表,我會寫一個存儲過程,在存儲過程中向表中插入兩條數據,第一條會插入成功,但是第二條會出錯,出錯之后事務就會回滾,讓第一條插入SQL也失敗。
use testdb; go if exists(select * from sysobjects where name ='testtransaction') drop procedure testtransaction go create procedure testtransaction @_user nchar(20), @_pwd nchar(20), @score decimal(6,2) as declare @error_count int set @error_count=0;--用於記錄錯誤信息的條數 begin begin begin transaction begin insert into userTable(_user,_pwd,score) values('賀蘭婷','love123',111);--這一條SQL會成功 insert into userTable(_user,_pwd,score) values(@_user,@_pwd,@score);--這一條SQL需要在外部調用存儲過程時傳遞參數 --手動讓錯誤條數加1,然后下面事務就會回滾 set @error_count = @error_count +1; set @error_count = @error_count + @@ERROR;--內部變量@@ERROR 這個表示如果上一條SQL語句出錯,那么這一條SQL語句就會執行,錯誤信息條數就會增加1 if @error_count >0 --如果錯誤信息條數大於0 證明在執行SQL的過程中出現了錯誤,則應當讓事務回滾 begin print('插入失敗!'); rollback transaction end else begin print('插入成功!'); commit transaction end end end end;
下面我們調用一下這個存儲過程
begin exec testtransaction '你好','你好呀!',8908; end
執行結果如下:
當插入失敗時事務會自動回滾到初始狀態,也就是說,我們插入成功的兩條數據會失敗!