EXECUTE错误后的事务计数

时间:2009-04-20 18:19:49

标签: sql-server ado.net

我的存储过程类似于:


CREATE PROCEDURE my_procedure 
  @val_1 INT,
  @val_2 INT
AS
SET NOCOUNT ON;
SET XACT_ABORT ON;

BEGIN TRY
  BEGIN TRANSACTION;

  INSERT INTO table_1(col_1, col_2)
  VALUES (@val_1, @val_2);  

  COMMIT TRANSACTION;
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION;

  DECLARE
    @ERROR_SEVERITY INT,
    @ERROR_STATE    INT,
    @ERROR_NUMBER   INT,
    @ERROR_LINE     INT,
    @ERROR_MESSAGE  NVARCHAR(4000);

  SELECT
    @ERROR_SEVERITY = ERROR_SEVERITY(),
    @ERROR_STATE    = ERROR_STATE(),
    @ERROR_NUMBER   = ERROR_NUMBER(),
    @ERROR_LINE     = ERROR_LINE(),
    @ERROR_MESSAGE  = ERROR_MESSAGE();

  RAISERROR('Msg %d,
  Line %d,
  :%s',
    @ERROR_SEVERITY,
    @ERROR_STATE,
    @ERROR_NUMBER,
    @ERROR_LINE,
    @ERROR_MESSAGE);
END CATCH

当通过数据库执行此代码时,一切都正常运行。通过ADO.NET执行时,我收到以下错误消息:

“INSERT语句与FOREIGN KEY约束”FK_table1_table2“冲突。冲突发生在数据库”my_database“,表”dbo.table_1“,列'col_1 '.EXECUTE后的事务计数表示缺少COMMIT或ROLLBACK TRANSACTION语句。前一个count = 1,当前count = 0.“

是否发生这种情况是因为XACT_ABORT设置强制回滚来自ADO.NET的事务?避免这个错误的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以在代码中检查XACT_STATE(),然后提交或回滚,请在此处查看:Use XACT_STATE() To Check For Doomed Transactions

基本上这样的事情会爆炸

BEGIN TRANSACTION TranA
    BEGIN TRY
     DECLARE  @cond INT;
     SET @cond =  'A';
    END TRY
    BEGIN CATCH
     PRINT 'a'
    END CATCH;
    COMMIT TRAN TranA

当你检查xact_state时你可以控制它

BEGIN TRANSACTION TranA
    BEGIN TRY
     DECLARE  @cond INT;
     SET @cond = 'A';
    END TRY
    BEGIN CATCH
     PRINT ERROR_MESSAGE();
    END CATCH;
    IF XACT_STATE() =0
    BEGIN
     COMMIT TRAN TranA
    END
    ELSE
    BEGIN
     ROLLBACK TRAN TranA
    END

另外看看这两个必读的链接 Implementing Error Handling with Stored ProceduresError Handling in SQL Server – a Background

答案 1 :(得分:2)

如果XACT_STATE()= 0 BEGIN COMMIT TRAN TranA END

会产生错误。 XACT_STATE()= 0表示没有要提交或回滚的事务

XACT_STATE()= 1表示存在可提交的事务

XACT_STATE()= -1表示在当前上下文结束时,数据库引擎将回滚不可交付的事务。