在命名交易时是否需要@@ Trancount?

时间:2017-01-04 12:07:04

标签: c# sql-server

我正在从我的代码中调用存储过程。在调用存储过程之前,我正在检查连接是否打开,如果没有,则打开连接。

存储过程具有以下正文:

begin try
  begin tran mytran;

  --do inserts here into my table

  commit tran mytran;

  --return id''s of inserted records
  select id from mytable;
end try
begin catch
  rollback tran mytran;
  throw;
end catch;

事务在存储过程中显式启动。以上是正确的还是我应该使用:

begin catch
  if @@trancount > 0
    rollback tran mytran;

  throw;
end catch;

其次,最终的select id from mytable;地方是正确的还是应该移到end catch区块以下?

1 个答案:

答案 0 :(得分:0)

首先,我建议您使用显式事务将SET XACT_ABORT ON;添加到存储过程。这将确保在查询取消或超时之后回滚事务,否则将阻止catch块执行并使事务保持未提交状态。

除非您使用保存点,否则ROLLBACK上指定的事务名称是多余的。在没有保存点的情况下,省略事务名称。没有保存点的ROLLBACK将回滚所有事务,无论是否根据SQL Server Books Online指定了事务名称。

SELECT块末尾的TRY只会在成功COMMIT之后返回结果集。如果发生错误,将不会返回任何结果集。

我建议在ROLLBACK之前检查@@ TRANCOUNT,以便无论会话XACT_ABORT设置如何,代码都能正常工作。

CREATE PROC dbo.Insert_MyTable
AS
SET XACT_ABORT, NOCOUNT ON;
BEGIN TRY
  BEGIN TRAN mytran;

  --do inserts here into my table

  COMMIT TRAN mytran;

  --return id''s of inserted records
  SELECT id FROM mytable;
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0 ROLLBACK;
  THROW;
END CATCH;
GO