SQL Server:BEGIN TRAN ...没有ROLLBACK的COMMIT不会回滚,具体取决于错误

时间:2018-05-21 16:05:29

标签: sql-server transactions commit rollback

在Microsoft SQL Server中,我使用

创建一个测试表
matrix = data[['1','2','3','4','5']]
print(np.sum([matrix[matrix_list['iteration']==i] for i in range(0,9)], axis=0))

然后当我跑:

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会产生错误

  

违反PRIMARY KEY约束' PK_Test'

但实际上表中包含insert (1, 'Three')的行。

如果我BookId = 1, 2, 4,那么我会得到预期的行为。

然后在错误就像

的情况下获取另一段代码
  

数据库' MyDatabase'的事务日志由于' ACTIVE_TRANSACTION'

已满

事务回滚有效

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

但我仍然想知道为什么没有ROLLBACK的BEGIN TRAN不能一直工作。我猜这真的取决于错误的类型吗?

1 个答案:

答案 0 :(得分:1)

  

但我仍然想知道为什么没有ROLLBACK的BEGIN TRAN不能一直工作。我猜这真的取决于错误的类型吗?

你是对的,这取决于错误的类型.Erland的声明让我更了解SQL Server中错误处理的不同变化。

  

SQL Server中的错误处理是一个非常混乱的故事。我问过你在1993年左右在comp.databases.sybase中所做的同样的问题。我不记得我到底得到了什么答案,但我认为他们不是很好。

     

但这就是故事:当SQL Server中发生错误时,批处理可能会中止并且事务会回滚。或者声明可以终止,并且交易继续。

     

请不要问这个逻辑,因为没有。数据完整性违规通常不会中止批处理。但转换错误通常会发生。

     

对于微软的辩护,可以说,当产品还是Sybase时,许多这些糟糕的决定是在加利福尼亚州做出的。另一方面,微软非常努力理顺这一点,恰恰相反。

请参阅以下屏幕截图,了解不同的情况

enter image description here

此链接提供有关每种行为的优秀信息

Error and Transaction Handling in SQL Server

此错误

  

数据库' MyDatabase'的事务日志由于' ACTIVE_TRANSACTION

而已满

可能由于多种原因而发生。一些包括

  1. 您有一个显示日志空间重用的活动事务
  2. 可能需要大量日志空间且磁盘可能已满的繁重交易
  3. 其他参考:

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