SQL SERVER TRANSACTION 事物

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 1.事务的概念 事物是一种机制,是一种操作序列,它包含了数据库一组操作命令,这组命令要么全部执行,要么都不执行。因此事物是一组不可分割的事物逻辑单元,在数据库进行并发操作时候,事物是作为最小的控制单元来使用的,这特别适用于多用户同时操作的数据通信系统。

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语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
3月前
|
SQL IDE Java
Java连接SQL Server数据库的详细操作流程
Java连接SQL Server数据库的详细操作流程
|
2月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
63 13
|
2月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
2月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
44 6
|
1月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
174 0
|
2月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
106 1
|
2月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
138 3
|
2月前
|
SQL 存储 安全
数据库数据恢复—SQL Server数据库出现逻辑错误的数据恢复案例
SQL Server数据库数据恢复环境: 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库,SQL Server数据库存放在D盘分区中。 SQL Server数据库故障: 存放SQL Server数据库的D盘分区容量不足,管理员在E盘中生成了一个.ndf的文件并且将数据库路径指向E盘继续使用。数据库继续运行一段时间后出现故障并报错,连接失效,SqlServer数据库无法附加查询。管理员多次尝试恢复数据库数据但是没有成功。
|
2月前
|
SQL 存储 关系型数据库
关系型数据库SQL Server学习
【7月更文挑战第4天】
48 2
|
3月前
|
SQL 存储 测试技术