为什么事务没有回滚!

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: --事务的原子性要求事务要么全部完成,要么全部不完成,不可能停滞在某个中间状态。

--事务的原子性要求事务要么全部完成,要么全部不完成,不可能停滞在某个中间状态。
--然而,我的事务却没有“回滚”,为此还导致了异常数据的发生,为什么?

这是一个发生在我工作中的真实的案例,在用户问我的时候我当时也SB了,
在我理解了这背后的原理后,我虽然接受了SQL Server在某些场景下不回滚的设计使然,但不得不吐槽,这个功能真不爽!
下面我利用一个样例来描述这个问题:

复制代码
--创建test1表
CREATE TABLE [dbo].[test1](
    [id] [int] NOT NULL,
    [testname] [varchar](10) NULL
) ON [PRIMARY]
GO
复制代码

现在执行一个事务,事务中包含两个insert操作,其中第一个insert操作的testname字段超过了最大长度10

复制代码
--显示执行一个事务,插入两行数据,其中第一行的testname字段超过了最大长度

         BEGIN TRANSACTION;
         --SELECT 1
         --FROM test;
         INSERT INTO [dbo].[test1]
                                  ([id], [testname]
                                  )
         VALUES
                (1, '123456789101'
                );
         INSERT INTO [dbo].[test1]
                                  ([id], [testname]
                                  )
         VALUES
                (888, '12345'
                );
         COMMIT TRANSACTION;
复制代码

如预料的一样,SQL Server在执行第一条语句时报错

image

“按理”说来,这个事务执行会失败,第二条插入语句会回滚,但实际结果却是:

select * from [dbo].[test1]

image

在某些场景下,这会导致异常数据的发生。

 

为什么会这样呢??

据MSDN,默认情况,SQL Server并不会回滚事务,即使事务中的某个语句报错,事务还是会继续执行下去,除非非常严重的错误(serverity level is greater or equals 16)。
这是由数据库选项XACT_ABORT决定的,默认XACT_ABORT为OFF,

When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing. Depending upon the severity of the error, the entire transaction may be rolled back even when SET XACT_ABORT is OFF. OFF is the default setting.

如果想规避这个问题,微软告诉我们需要把XACT_ABORT设置为On,这样一个事务中任务一个语句报错都会导致整个事务回滚。

SET XACT_ABORT ON

当然,你也可以使用try、catch人工捕获错误以便进行回滚或者在程序中使用事务。

 

我在想为什么会有这么DT的设计呢?

我们学事务的第一堂课里面就讲了事务的原子性要求:事务要么全部执行,要么全部失败,不会存在中间状态。
但SQL Server为什么默认不回滚呢?百思不得其解。
求助MSDN时邹大侠给的一个解释虽然有道理(谢谢邹大侠),但还是觉得不够完美,因为即使是为了能够让开发人员自己来控制事务的状态,也不应该把XACT_ABORT默认设置为OFF,相反,如果设置为On倒是可以接受。

 

image

 

期待其他大神们给予指导。

相关实践学习
使用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
目录
相关文章
|
5月前
|
SQL Oracle 关系型数据库
第7章 事务
第7章 事务
28 0
|
7月前
|
存储 Java 中间件
事务一致性测试
事务一致性测试
54 0
手动回滚、提交事务
手动回滚、提交事务
63 1
|
7月前
|
SQL 前端开发 大数据
什么是大事务?以及大事务产生的问题
什么是大事务?以及大事务产生的问题
192 0
|
存储 Oracle 固态存储
深入理解事务
事务将应用程序的多个读、写操作捆绑在一起成为一个逻辑执行单元。即事务中的所有读写是一个执行的整体,整 个事务要么成功(提交)、要么失败(中止 或者 回滚)。如果失败,应用程序可以安全地重试。
16438 0
深入理解事务
|
人工智能 关系型数据库 MySQL
事务详解
事务是逻辑上的一组操作,要么都执行,要么都不执行。
75 0
|
SQL 存储 关系型数据库
|
SQL Java 大数据
事务详解(2)
你好看官,里面请!今天笔者讲的是事务。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
170 1
|
数据库
什么时候需要使用事务
什么时候需要使用事务
607 0
|
Oracle 安全 Java
事务详解(1)
你好看官,里面请!今天笔者讲的是事务。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
107 2