SQL Server : BEGIN TRAN ... COMMIT without ROLLBACK 不回滚取决于错误

SQL Server : BEGIN TRAN ... COMMIT without ROLLBACK does not rollback depending on the error

在 Microsoft SQL 服务器中,我创建了一个测试 table

CREATE TABLE [Test]
(
    [BookID] [int] NOT NULL,
    [Name] [varchar](512) NOT NULL,

    CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([BookID] ASC)
) ON [PRIMARY]

然后当我运行:

BEGIN TRAN;

INSERT INTO Test (BookID, Name) Values (1,'one');
INSERT INTO Test (BookID, Name) Values (2,'Two');
INSERT INTO Test (BookID, Name) Values (1,'Three');
INSERT INTO Test (BookID, Name) Values (4,'Four');

COMMIT TRAN;

我希望 Test 中没有任何内容,因为 insert (1, 'Three') 会生成错误

Violation of PRIMARY KEY constraint 'PK_Test'

但实际上带有 BookId = 1, 2, 4 的行在 table.

如果我 SET XACT_ABORT ON,那么我会得到预期的行为。

然后当错误像

时再写一段代码

The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION'

事务回滚有效

为了确保我得到回滚,我应该将该语句包含在 TRY ... COMMIT CATCH ROLLBACK 语句中。

但我还是想知道为什么不带ROLLBACK的BEGIN TRAN总是不行。它真的像我猜的那样取决于错误类型吗?

But I am still wondering why the BEGIN TRAN without ROLLBACK does not work all the time. Does it really depend on the type of error as I guess?

你是对的,这取决于 Erland 的 error.Below 语句的类型帮助我更多地了解 SQL 服务器中错误处理的不同变体。

Error handling in SQL Server is a very messy story. I asked the same question as you did in comp.databases.sybase in 1993 or so. I don't remember exactly what answers I got, but I don't think they were very good.

But this is the story: when an error occurs in SQL Server, the batch may be aborted and the transaction rolled back. Or the statement may be terminated, and the transaction continues.

Please don't ask about the logic in this, because there isn't any. Data-integrity violations usually don't abort the batch. But a conversion error often do.

To Microsoft's defence it can be said, that many of these bad decisions were taken in California when the product was still Sybase. On the other hand, Microsoft has very much effort to straighten out this, rather the opposite.

不同场景见下方截图

这个 link 对每个行为都有很好的信息

Error and Transaction Handling in SQL Server

这个错误

The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION

发生的原因有很多。一些包括

  1. 您有一个正在呈现日志的活动事务space重用
  2. 可能需要大量日志的繁重事务space并且您的磁盘可能已满

补充参考:

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6ae24a04-0ad3-4aba-b471-2bbbcd8d8626/with-the-transaction-primary-key-violation-error?forum=transactsql