代码之家  ›  专栏  ›  技术社区  ›  Fredou

打印“成功”会导致begin trans/begin try commit/end try出错?

  •  1
  • Fredou  · 技术社区  · 14 年前

    所以我看到了一个奇怪的行为

    在一个脚本中,有如下内容:

      begin transaction
      begin try
    
           stuff
           stuff
           stuff
    
           print 'commit'
           commit transaction
      end try
      begin catch
           print 'rollback'
           print error_message()
           rollback transaction
      end catch
    

    事情是当这个脚本在运行时,我看到了print commit消息,但它不会进行commit并锁定表/行等。

    我必须通过选择该行并运行它来手动运行提交。

    但是如果我这样做

     begin transaction
      begin try
    
           stuff
           stuff
           stuff
    
           commit transaction
           print 'commit'
      end try
      begin catch
           print error_message()
           rollback transaction
           print 'rollback'
      end catch
    

    (交换了打印和提交)

    它很好用。

    有人知道为什么会这样吗?

    1 回复  |  直到 14 年前
        1
  •  2
  •   KM.    14 年前

    这对我来说很好:

    --create table t (rowid int)  --create one time before running script
    
    begin transaction
      begin try
    
           insert into t values (1)
           print 'commit'
           print XACT_STATE()   --should be 1
           commit transaction
           print XACT_STATE()   --should be 0
      end try
      begin catch
           print ERROR_MESSAGE()
           rollback transaction
           print 'rollback'
      end catch
    
    select * from t
    

    输出

    commit
    1
    0
    rowid
    -----------
    1
    

    关闭SSMS窗口,打开一个新窗口,然后再次运行第一个脚本,我敢打赌第一次运行时您有一个打开的事务,所以您需要额外的提交。

    编辑 操作注释后:

    在到每个数据库的新连接中运行此准确的脚本:

    BEGIN TRY create table t (rowid int) END TRY BEGIN CATCH END CATCH
    
    print 'A - XACT_STATE()='+ISNULL(CONVERT(varchar(10),XACT_STATE()),'')+', @@TRANCOUNT='+ISNULL(CONVERT(varchar(10),@@TRANCOUNT),'')
    
    begin transaction
      begin try
    
           insert into t values (1)
           print 'commit'
           print 'B - XACT_STATE()='+ISNULL(CONVERT(varchar(10),XACT_STATE()),'')+', @@TRANCOUNT='+ISNULL(CONVERT(varchar(10),@@TRANCOUNT),'')
           commit transaction
           print 'C - XACT_STATE()='+ISNULL(CONVERT(varchar(10),XACT_STATE()),'')+', @@TRANCOUNT='+ISNULL(CONVERT(varchar(10),@@TRANCOUNT),'')
      end try
      begin catch
           print ERROR_MESSAGE()
           rollback transaction
           print 'rollback'
      end catch
    
    print 'D - XACT_STATE()='+ISNULL(CONVERT(varchar(10),XACT_STATE()),'')+', @@TRANCOUNT='+ISNULL(CONVERT(varchar(10),@@TRANCOUNT),'')
    
    select * from t
    

    你应该得到:

    A - XACT_STATE()=0, @@TRANCOUNT=0
    
    (1 row(s) affected)
    commit
    B - XACT_STATE()=1, @@TRANCOUNT=1
    C - XACT_STATE()=0, @@TRANCOUNT=0
    D - XACT_STATE()=0, @@TRANCOUNT=0
    rowid
    -----------
    1
    
    (1 row(s) affected)