事務的概念及要求
- 事務(transaction)是作為單個邏輯工作單元執(zhí)行的一系列操作贺归。
- 多個操作作為一個整體向系統(tǒng)提交淆两,要么都執(zhí)行,要么都不執(zhí)行拂酣。
- 事務是一個不可再分割的工作邏輯單元秋冰。
銀行轉(zhuǎn)賬過程就是一個事務
- 它需要兩條update語句來完成,這兩條語句是一個整體婶熬。
- 如果其中任一條出現(xiàn)錯誤,則整個轉(zhuǎn)賬業(yè)務也取消盯另,兩個賬戶中的余額應恢復到原來的數(shù)據(jù)商蕴,從而確保轉(zhuǎn)賬前和轉(zhuǎn)賬后的余額不變。
事務的特性
- 原子性:事務是一個完整的操作,事務的各步操作是不可分割的,要么都執(zhí)行决采,要么都不執(zhí)行。
- 一致性:當事務完成時,數(shù)據(jù)必須處于一致狀態(tài)厨埋。
- 隔離性:并發(fā)事務之間彼此隔離、獨立,它不應該以任何方式依賴于或影響其他事務据悔。
- 永久性:事務完成后群嗤,它對數(shù)據(jù)的修改被永久保存。
事務的分類
- 顯式事務:用BEGIN TRANSACTION明確指定事務的開始破衔,最常用的事務類型。
- 隱性事務:通過設(shè)置SET IMPLICIT_TRANSACTION ON語句,將隱性事務模式設(shè)置為打開,其后的T-SQL語句自動啟動一個新事務盼砍。提交或回滾一個事務后,下一個T-SQL語句又將啟動一個新事務。
- 自動提交事務:SQLServer的默認模式觉渴;每條單獨的T-SQL語句視為一個事務踢京。
使用SQL語句管理事務的基本步驟
--開始事務
BEGIN TRANSACTION
--提交事務
COMMIT TRANSACTION
--回滾(撤銷)事務
ROLLBACK TRANSACTION
事務處理的關(guān)鍵問題:對事務中的insert、update蹬屹、delete語句實時跟蹤
判斷某條語句執(zhí)行是否出錯的方法
- 使用全局變量@@ERROR
- @@ERROR只判斷當前一條T-SQL語句執(zhí)行是否有錯
- 為了判斷事務中所有的T-SQL語句是否有錯,可以對錯誤進行累計
use StudentManageDB
go
declare @errorSum int--定義變量,用于累計事務執(zhí)行中的錯誤
set @errorSum=0 --初始化為,代表沒有錯誤
begin transaction
begin
--轉(zhuǎn)出
update CardAccount set CurrentMoney-1000 where StudentId=100001
set @errorSum=@errorSum+@@ERROR
--轉(zhuǎn)入
update CardAccount set CurrentMoney+1000 where StudentId=100002
set @errorSum=@errorSum+@@ERROR --累計是否有錯誤
if(@errorSum>0)
rollback transaction
else
commit transaction
end
go
事務的應用
--編寫存儲過程,實現(xiàn)學員一卡通轉(zhuǎn)賬功能,要求用戶輸入轉(zhuǎn)入和轉(zhuǎn)出的金額和賬戶
use StudentManageDB
go
if exists(select * from Sysobjects where name='usp_TransferAccounts')
drop procedure usp_TransferAccounts
go
create procedure usp_TransferAccounts
@inputAcount int,--轉(zhuǎn)入賬戶
@outputAccount int, --轉(zhuǎn)出賬戶
@transferMoney int --交易金額
as
declare @errorSum int--定義變量完慧,用于累計事務執(zhí)行中的錯誤
set @errorSum=0 --初始化為册着,代表沒有錯誤
begin transaction
begin
--轉(zhuǎn)出
update CardAccount set CurrentMoney-@transferMoney where StudentId=@outputAccount
set @errorSum=@errorSum+@@ERROR
--轉(zhuǎn)入
update CardAccount set CurrentMoney+@transferMoney where StudentId=@inputAcount
set @errorSum=@errorSum+@@ERROR --累計是否有錯誤
if(@errorSum>0)
rollback transaction
else
commit transaction
end
go