事物是一種機制,是一種操作序列,它包含了資料庫一組操作命令,這組命令要麼全部執行,要麼都不執行。因此事物是一組不可分割的事物邏輯單元,在資料庫進行併發操作時候,事物是作為最小的控制單元來使用的,這特別適用於多用戶同時操作的數據通信系統。例如:訂票、銀行、保險公司以及證券交易系統等。 ...
1.事務的概念
事物是一種機制,是一種操作序列,它包含了資料庫一組操作命令,這組命令要麼全部執行,要麼都不執行。因此事物是一組不可分割的事物邏輯單元,在資料庫進行併發操作時候,事物是作為最小的控制單元來使用的,這特別適用於多用戶同時操作的數據通信系統。例如:訂票、銀行、保險公司以及證券交易系統等。
2.事物的4大屬性
- 原子性:事物是一個完整的操作;
- 隔離性:對數據進行修改的所有併發事物都是彼此隔離的;
- 一致性:當事物完成時,事物必須處於一致的狀態;
- 持久性:事物完成後,對於系統的影響是永久的;
3.創建事物
- 開始事物:transaction begin
- 提交事物:commit transaction
- 回滾事物:rollback transaction
4.事物的分類
- 顯示事物:用begin transaction 明確指定事物的開始,用commit transaction, rollback transaction來結束或者回滾事務
- 隱示事物(自動提交事物):隱式事務則在執完語句後自動提交事務
5.事例
實現轉賬操作,轉賬人出賬和收賬人入賬是一組完整的操作序列,必須全部完成或不完成,準備一張用戶錢包表(tbUserWallet),轉賬交易記錄表(tbTransaction),簡單設計如下
向用戶錢包表(tbUserWallet)添加測試數據
創建轉賬存儲事物
USE [TEST] GO /****** Object: StoredProcedure [dbo].[pAddTransaction] Script Date: 2018/5/21 12:44:59 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: yangyi -- Create date: 18/05/21 -- Description: 轉賬 -- ============================================= CREATE PROCEDURE [dbo].[pAddTransaction] @InOpenID uniqueidentifier, @InTDesc nvarchar(50), @OutOpenID uniqueidentifier, @OutTDesc nvarchar(50), @TAmount decimal(10, 2), @TTID int, @Result int output AS BEGIN IF((SELECT Amount FROM tbUserWallet WHERE OpenID=@OutOpenID)>=@TAmount) BEGIN BEGIN TRANSACTION BEGIN TRY UPDATE tbUserWallet SET Amount=Amount-@TAmount WHERE OpenID=@OutOpenID UPDATE tbUserWallet SET Amount=Amount+@TAmount WHERE OpenID=@InOpenID --SELECT 1+'A' INSERT INTO [dbo].[tbTransaction]([TID],[OpenID],[TAmount],[TTID],[TDesc],[CreateDT])VALUES(NEWID(),@InOpenID,@TAmount,@TTID,@InTDesc,GETDATE()) INSERT INTO [dbo].[tbTransaction]([TID],[OpenID],[TAmount],[TTID],[TDesc],[CreateDT])VALUES(NEWID(),@OutOpenID,-@TAmount,@TTID,@OutTDesc,GETDATE()) END TRY BEGIN CATCH IF(@@TRANCOUNT>0) BEGIN SET @Result=-1 PRINT '事物執行出錯,回滾' ROLLBACK TRANSACTION END END CATCH IF(@@TRANCOUNT>0) BEGIN SET @Result=1 PRINT '一切按預期計劃執行' COMMIT TRANSACTION END END ELSE BEGIN PRINT '轉賬人金額不足' SET @Result=0 END END GO
測試1>:轉賬人金額不足測試
USE [TEST] GO DECLARE @return_value int, @Result int EXEC @return_value = [dbo].[pAddTransaction] @InOpenID = '1ccd524d-de62-47ca-87d3-38787b040ba3', @InTDesc = N'收到A的轉賬100', @OutOpenID = '2ccd524d-de62-47ca-87d3-38787b040ba3', @OutTDesc = N'轉賬給A100', @TAmount = 100, @TTID = 1, @Result = @Result OUTPUT SELECT @Result as N'@Result' GO
測試2>:模擬事物出現錯誤,進行回滾
取消存儲事物中的:SELECT 1+'A' 註釋(模擬事物中發生錯誤)
USE [TEST] GO DECLARE @return_value int, @Result int EXEC @return_value = [dbo].[pAddTransaction] @InOpenID = '2ccd524d-de62-47ca-87d3-38787b040ba3', @InTDesc = N'收到A的轉賬100', @OutOpenID = '1ccd524d-de62-47ca-87d3-38787b040ba3', @OutTDesc = N'轉賬給A100', @TAmount = 100, @TTID = 1, @Result = @Result OUTPUT SELECT @Result as N'@Result' GO
測試3.>執行成功測試,註釋 SELECT 1+'A'
USE [TEST] GO DECLARE @return_value int, @Result int EXEC @return_value = [dbo].[pAddTransaction] @InOpenID = '2ccd524d-de62-47ca-87d3-38787b040ba3', @InTDesc = N'收到A的轉賬100', @OutOpenID = '1ccd524d-de62-47ca-87d3-38787b040ba3', @OutTDesc = N'轉賬給A100', @TAmount = 100, @TTID = 1, @Result = @Result OUTPUT SELECT @Result as N'@Result' GO