SQL SERVER TRANSACTION 事物

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL SERVER TRANSACTION 事物相关的知识,希望对你有一定的参考价值。

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

 

以上是关于SQL SERVER TRANSACTION 事物的主要内容,如果未能解决你的问题,请参考以下文章

sql中事物

SQL Server Transaction Log Truncate && Shrink

事务 Transaction的那些事

SQL Server 数据库的维护__事务(transaction)和锁

SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

Sql Server 事物