SQL SERVER TRANSACTION 事物

1.事務的概念

事物是一種機制,是一種操做序列,它包含了數據庫一組操做命令,這組命令要麼所有執行,要麼都不執行。所以事物是一組不可分割的事物邏輯單元,在數據庫進行併發操做時候,事物是做爲最小的控制單元來使用的,這特別適用於多用戶同時操做的數據通訊系統。例如:訂票、銀行、保險公司以及證券交易系統等。sql

2.事物的4大屬性

  • 原子性:事物是一個完整的操做;
  • 隔離性:對數據進行修改的全部併發事物都是彼此隔離的;
  • 一致性:當事物完成時,事物必須處於一致的狀態;
  • 持久性:事物完成後,對於系統的影響是永久的;

3.建立事物

  • 開始事物:transaction begin
  • 提交事物:commit transaction
  • 回滾事物:rollback transaction

4.事物的分類

  • 顯示事物:用begin transaction 明確指定事物的開始,用commit transaction, rollback transaction來結束或者回滾事務
  • 隱示事物(自動提交事物):隱式事務則在執完語句後自動提交事務

5.事例

 實現轉帳操做,轉帳人出帳和收帳人入帳是一組完整的操做序列,必須所有完成或不完成,準備一張用戶錢包表(tbUserWallet),轉帳交易記錄表(tbTransaction),簡單設計以下數據庫

 

向用戶錢包表(tbUserWallet)添加測試數據併發

建立轉帳存儲事物ide

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' 註釋(模擬事物中發生錯誤)3d

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' blog

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

相關文章
相關標籤/搜索