为什么在CREATE语句失败时Microsoft SQL Server会隐式回滚?

时间:2011-05-04 00:15:20

标签: sql-server-2005

我正在研究python MSSQL驱动程序pymssql。我遇到了一个有趣的情况,我似乎无法找到文档。似乎当CREATE TABLE语句失败时,它运行的事务将被隐式回滚:

-- shows 0
select @@TRANCOUNT
BEGIN TRAN

-- will cause an error
INSERT INTO foobar values ('baz')

-- shows 1 as expected
select @@TRANCOUNT

-- will cause an error
CREATE TABLE badschema.t1 (
    test1 CHAR(5) NOT NULL
)

-- shows 0, this is not expected
select @@TRANCOUNT

我想了解为什么会发生这种情况并知道是否有描述情况的文档。我将在驱动程序中编写此行为的代码,但我想确保我对隐式回滚事务的任何其他错误类型执行此操作。

注意

我并不关心典型的交易行为。我特别想知道为什么在CREATE语句失败但没有INSERT语句的情况下给出隐式回滚。

3 个答案:

答案 0 :(得分:1)

通常(但并非总是),如果事件的任何部分失败,则回滚整个事件的强点http://www.firstsql.com/tutor5.htm

使用事务的最常见原因之一是当您需要将操作设置为原子时:

  

计算机中的原子操作   科学是指一系列操作   可以结合使他们   在系统的其他部分看起来是   一次只有两次操作   可能的结果:成功或失败。   en.wikipedia.org/wiki/Atomic_(computer_science)

可能没有记录,因为,如果我正确理解您的示例,则假定您通过使用BEGIN TRAN开始交易来实现该功能

答案 1 :(得分:1)

以下是Sql Server中错误处理的权威指南:
http://www.sommarskog.se/error-handling-I.html

这很长,但是很好,它是为Sql Server 2000编写的,但大部分内容仍然准确。你要找的部分在这里:
http://www.sommarskog.se/error-handling-I.html#whathappens

在您的情况下,文章说Sql Server正在执行批量堕胎,并且它将在以下情况下采取此措施:

  • 大多数转换错误,例如将非数字字符串转换为数字值。
  • 无参数存储过程的多余参数。
  • 超过存储过程,触发器和函数的最大嵌套级别。
  • 被选为死锁受害者。
  • INSERT-EXEC中的列数不匹配。
  • 用尽数据文件或事务日志的空间。

还有更多内容,所以请务必阅读整个部分。

答案 2 :(得分:1)

如果您作为一个批处理(我第一次执行)运行,则事务保持打开状态,因为INSERT中止批处理并且不运行CREATE TABLE。只有逐行运行,事务才会回滚

您还可以通过设置SET XACT_ABORT ON.

为INSERT生成隐式回滚

我的猜测(我输入上面的句子只是一个灯泡时刻)是CREATE TABLE在实践中使用SET XACT_ABORT ON internalls =隐式回滚

关于SET XACT_ABORT的更多关于我的信息(我们在所有代码中使用它,因为它在客户端CommandTimeout上释放锁并回滚TXN)