【问题标题】:Commit transaction without begin transaction提交事务而不开始事务
【发布时间】:2019-09-13 05:59:28
【问题描述】:

我不小心遇到了一个情况,我没有把Begin Transaction放在我的存储过程的开头,而是写了Commit Transaction,如下所示

ALTER  PROCEDURE dbo.spTest
AS
BEGIN

DECLARE @MyId INT=1

BEGIN TRY 
UPDATE Test
SET
    -- Id -- this column value is auto-generated
    CharName = 'david'
WHERE id=4

--Just to test locking behavior 
WHILE(1=1)
BEGIN
    SET @MyId=2;
END


COMMIT TRANSACTION 
END TRY 

BEGIN CATCH
ROLLBACK TRANSACTION 
END CATCH 

END

我预计 SQL Server 会给我一个运行时错误,但它没有发生。当然我应该提一下,根据我的测试,由于缺少Begin Transaction,它没有在桌子上获得任何锁,但在这种情况下COMMIT TRANSACTIONROLLBACK TRANSACTION 的意义何在? SQL Server 引发任何错误?

编辑: 如果我删除 while 块并在到达 COMMIT TRANSACTION 时放置 WaitFor Sql 引发错误

ALTER  PROCEDURE dbo.spTest
AS
BEGIN


    UPDATE Test
    SET  CharName = 'david'
    WHERE id=4

      PRINT 'waiting for a minute '
      WAITFOR DELAY '00:00:10';


  COMMIT TRANSACTION 

END

现在我收到此错误

COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION

【问题讨论】:

  • 表上的锁(或更准确地说:上的锁)独立与您是否定义/启动了显式事务无关。如果你没有,那么每个语句都在它自己的隐式事务中运行,并且锁被应用
  • 这是没有意义的——如果没有BEGIN TRANSACTION,那么就没有明确的事务到位——在这种情况下调用COMMIT TRANSACTIONROLLBACK TRANSACTION相当于“无操作”——它没有'什么都不做,它没有任何好处......
  • 但是如果我没有在内部定义显式事务,而块表的更改已经提交并且行上没有锁
  • 设置一个 变量 无论如何都与表/行锁没有任何关系.....这将起作用 即使 IF上面更新的行仍然被锁定.....这整个sn-p代码似乎相当可疑,似乎没有任何实际用途 - 其他让后来的读者感到困惑......
  • 如果 sql server 没有引发任何错误毫无意义,因为它没有链接到任何事务

标签: sql-server


【解决方案1】:

在这种情况下,COMMIT TRANSACTION 和 ROLLBACK TRANSACTION 的意义何在?

在这种情况下没有意义

为什么 SQL Server 没有引发任何错误?

我没有看到任何会引发错误的代码。如果您能解释您认为应该在何处以及为什么提出错误,这将有所帮助

关于你在这里实际做的任何事情;

如果此过程的目的是保持交易处于打开状态,则您需要更多类似的东西:

ALTER  PROCEDURE dbo.spTest
AS
BEGIN

  BEGIN TRANSACTION
    UPDATE Test
    SET  CharName = 'david'
    WHERE id=4

    --Endless loop
    WHILE(1=1)
    BEGIN
      PRINT 'waiting for a minute inside a transaction. Try something from another session'
      WAITFOR DELAY '00:01';
    END

  -- Transaction will actually never be committed 
  -- Because this line will never be reached
  -- because it's preceded by an endless loop
  COMMIT TRANSACTION 

END

TRY / CATCH 有点让人分心。我已经删除了。

【讨论】:

  • 感谢@Nick,我认为在这种情况下,我们可以删除 while 块并放置 WAITFOR DELAY
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-21
  • 1970-01-01
相关资源
最近更新 更多