1. 程式人生 > >SQLSERVER之事務TRANSACTION筆記

SQLSERVER之事務TRANSACTION筆記

--【一】
--為什麼需要事務?
--假如有兩個金額賬戶A和B,A賬戶有500元,B賬戶有2000元。現在要將A賬戶裡的500元轉賬給B賬戶。但有個條件約束,設定為賬戶金額不能小於1.
--執行語句如下:
--UPDATE BANK SET MONEY=MONEY-500 WHERE NAME='A'
--UPDATE BANK SET MONEY=MONEY+500 WHERE NAME='B'
--在執行以上語句的時候,會因為A賬戶的金額減少500等於0而被終止語句,便B賬戶卻會多出500元,這樣,在銀行的總賬戶裡就會多出500元,也就是銀行虧損了500元


--為了保證執行語句的完整性,將要使用事務




--事務的概念以及特性
/*
事務(TRANSACTION)是作為單個邏輯工作單元執行的一系列操作
多個操作作為一個整體向系統提交,要麼都執行,要麼都不執行
事務是一個不可分割的工作邏輯單元


轉賬過程就是一個事務


它需要兩條UPDATE語句來完成,這兩條語句是一個整體
如果其中任何一條出現錯誤,則整個轉賬業務也應取消
兩個賬戶中的餘額應恢復到原來的資料
從而確保轉賬前和轉賬後的餘額不變
*/


--【二】
--事務的特性
/*
事務必須具備以下四個屬性,簡稱ACID屬性:
原子性(Atomicity)
事務是一個完整的操作,事務的各步操作是不可分的(原子的);要麼都執行,要麼都不執行


一致性(Consistency)
當事務完成時,資料必須處於一致狀態


隔離性(Lsolation)
張三和李四之間的轉賬與王五和趙二之間的轉賬,永遠是相互獨立的。(併發事務之間相互獨立)


永久性(Durability)
事務完成後,它對資料庫的修改被永久儲存
*/


--【三】
/*
開始事務 BEGIN TRANSACTION
提交事務 COMMIT TRANSACTION
回滾(撤消)事務 ROLLABCK TRANSACTION


一旦事務提交或回滾,則事務結束
操作步驟:
1)BEGIN TRAN
2)宣告變數用於累加錯誤號,錯誤號使用全域性變數@@ERROR
3)為2)中宣告的變數賦初始值為0
4)增、刪、改的T-SQL語句
5)SET @變數
[email protected]
變數[email protected]@ERROR --累計錯誤號


重複4)、5)直到所有的業務完成
6)使用IF...ELSE判斷累加的錯誤號是否>0,大於就回滾,否則就提交
*/


USE E_Market
GO
--檢視轉發之前的全額
SELECT * FROM BANK
GO


--開始事務,從此處開始,後續的T-SQL語句是一個整體
--【1、開始事務】
BEGIN TRAN
--【2、定義變數,用於累計事務執行過程中的錯誤】
DECLARE @error int 
--【3、給該變數賦值】
SET @error=0  --set一般用來變數賦值,select一般將查詢出來的值賦給變數
--【4、開始執行轉賬】
UPDATE BANK SET MONEY=MONEY-500 WHERE NAME='A'
--【5、累加錯誤】
SET @
[email protected]
[email protected]@ERROR
--重擔執行步驟4、5
UPDATE BANK SET MONEY=MONEY+500 WHERE NAME='B'
SET @[email protected][email protected]@ERROR


--【6、使用IF...ELSE去判斷累加的錯誤號,確定事務是提交是回滾】
IF (@error>0)
BEGIN
PRINT'交易失敗!回滾事務'
ROLLBACK TRAN
END
ELSE
BEGIN
PRINT'交易成功,提交事務,寫入硬碟'
COMMIT TRAN
END
GO


--【三】
-- 巢狀事務及事務分類
/*
.全域性變數@@TRANCOUNT,返回當前連線的活動事務數量


.顯示事務,用BEGIN TRANSACTION明確指定事務的開始最常用的事務型別


.隱性事務,通過設定SET IMPLICIT_TRANSACTIONS ON語句,將隱性事務模式設定為開啟
其後的T-SQL語句自動啟動一個新事務
提交或回滾一個事務後,下一個T-SQL語句又將啟動一個新事務


.自動提交事務
SQL SERVER 的預設模式
每條單獨的T-SQL語句將視為一個事務
*/


--COMMIT提交,對事務的影響(使用巢狀事務)
PRINT @@TRANCOUNT --在沒有事務的時候,檢視一下事務數量
BEGIN TRAN --開始第一個事務
PRINT @@TRANCOUNT --開始事務,@@TRANCOUNT將被置為1


BEGIN TRAN --開始第二個事務
PRINT @@TRANCOUNT --事務數+1 


COMMIT TRAN --提交第二個事務
PRINT @@TRANCOUNT --事務數-1


COMMIT TRAN --提交第一個事務,事務數-1
PRINT @@TRANCOUNT


GO


-- ROLLBACK回滾,對事務數量的影響
PRINT @@TRANCOUNT --在沒有事務的時候,檢視一下事務數量
BEGIN TRAN --開始第一個事務
PRINT @@TRANCOUNT --開始事務,@@TRANCOUNT將被置為1


BEGIN TRAN --開始第二個事務
PRINT @@TRANCOUNT --事務數+1 


ROLLBACK TRAN --回滾事務將清零,所有活動事務都將回滾
PRINT @@TRANCOUNT


GO


--顯示事務
USE E_Market
GO
SET NOCOUNT ON --設定不顯示受影響行數(不是本章知識點,可忽略)


--設定為顯示事務模式
SET IMPLICIT_TRANSACTIONS OFF
GO
PRINT'開始事務數:'+CAST(@@TRANCOUNT AS VARCHAR(10))
GO
IF EXISTS(SELECT * FROM SYSOBJECTS WHERE NAME='Table1')
DROP TALBE Table1
GO
CREATE TALBE TABLE1
(
COL1 INT
)
-- 向表中插入一條資料
INNSERT INTO TABLE1 VALUES(1)
PRINT'使用顯示事務數量為:'+CAST(@@TRANCOUNT AS VARCAHR(10))
BEGIN TRAN
PRINT '顯示事務的個數:'+CAST(@@TRANCOUNT AS VARCAHR(10))
COMMIT TRAN --提交事務
GO
PIRNT '顯示事務的個數是:'+CAST(@@TRANCOUNT AS VARCHAR(10))
GO


--結果為:通過【SET IMPLICIT_TRANSACTIONS OFF】關閉隱式事務,在向資料庫插入一條資訊的時候,所以事務數是0.在通過begin建立事務後,顯示事務數為1.提交事務後,整數務變為0




--設定為隱式事務模式
PRINT '設定為隱式事務模式'
SET IMPLICIT_TRANSACTIONS ON --顯啟隱式開啟
INNSERT INTO TABLE1 VALUES(2)
PRINT '使用事務數:'+CAST (@@TRANCOUNT AS VARCHAR(10))
COMMIT TRAN --提交事務,如果不提交,將在執行下面任意一條語句中自動開啟下一個事務,包括所有的CREATE,TRUNCATE TABLE,INSERT,SELECT,ALTER TABLE,GRANT,UPDATE,所有的DROP,ROVOK,DELETE都將自動開啟下一個事務
PRINT '顯示提交後的事務數量:'+CAST(@@TRANCOUNT AS VARCHAR(10))
GO
--結果:由於開啟了隱式模式,在插入語句的時候,將自動建立一個事務,事務數為1




--自動提交事務
--當設定IMPLICIT_TRANSACTIONS OFF (也就是顯示模式的時候,就開啟了自動提交模式)
SET IMPLICIT_TRANSACTIONS OFF --設定為顯示事務模式,也就是恢復成了自動提交模式
INNSERT INTO TABLE1 VALUES(3) --如果沒有錯誤,直接提交 
PRINT @@TRANCOUNT --事務數為0


INNSERT INTO TABLE1 VALUES (5,4) --這裡會出現錯誤,會自動回滾
PRINT @@TRANCOUNT --事務數為0,由於已經回滾,事務數也是0


--【四】
--事務的相關問題
/*
對資料庫的操作方式分為序列方式與併發方式
事務併發所產生的問題
.資料丟失更新:兩個事務同時一組資料項更新,導致後面的更新覆蓋前面的更新
.讀髒資料:一個事務正在讀另一個更新事務沿未提交的資料
.不可重複讀:當一個事務讀取某一資料後,另一事務對該資料執行新操作,使得第一個事務無法再次讀取與前一次相同的結果。

解決併發事務的問題的解決方案--封鎖
共享鎖:一個數據物件上已存在共享鎖時,其他事務可以讀取資料,但不能修改資料
排他鎖:它所鎖定的資源,其他事務不能讀取也不能修改
更新鎖:在修改操作的初始化階段用來鎖定可能要被修改的資源
意向鎖:意向鎖表示一個事務為了訪問資料庫物件放置在資源層次結構的一個級別上的鎖,以保護較低級別資源上的共享或排它鎖。


隔離級別:
未授權讀取:允許讀取髒資料,但不允許更新丟失,如果一個事務已經開始寫資料,則允許其他事務讀此資料,但不允許同時進行寫操作
授權讀取:讀取資料的事務允許其他並行事務訪問該資料,但是未提交的寫事務將禁止其他事務和軸時訪問該資料
可重複讀取:禁止不可重複讀和讀髒資料,但有時可能出現幻讀資料。
序列化:它葽事務序列化執行,即事務只能一個接著一個地執行。
*/