我正在从我的代码中调用存储过程。在调用存储过程之前,我正在检查连接是否打开,如果没有,则打开连接。
存储过程具有以下正文:
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
区块以下?
答案 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