【问题标题】:Question with XACT_STATE() value inside a Catch blockCatch 块内的 XACT_STATE() 值问题
【发布时间】:2020-04-09 08:48:08
【问题描述】:

我对 xact_state 函数的错误提供的值有疑问。这是我的代码:

IF OBJECT_ID(N'dbo.Products', N'U') IS NOT NULL
    DROP TABLE dbo.Products

CREATE TABLE Products (
    ProductID int  NOT NULL PRIMARY KEY,
    ProductName nvarchar(100) null,
    UnitPrice decimal(18,2) not null,
    UnitsInStock int not null,
    UnitsOnOrder int null,
    DateIn datetime
);
GO

create or alter procedure InsertProduct(
    @ProductId int,
    @ProductName nvarchar(100),
    @UnitPrice decimal(18,2),
    @UnitsInStock int,
    @UnitsOnOrder int
)
as
begin
    begin try
        begin transaction

        insert  into Products(ProductID, ProductName, UnitPrice, UnitsInStock, UnitsOnOrder, DateIn)
            values(@ProductID, @ProductName, @UnitPrice, @UnitsInStock, @UnitsOnOrder, GETDATE())

        commit transaction 
    end try
    begin catch
        print N'value of XACT_STATE()' + convert(nvarchar(20),XACT_STATE());
        if XACT_STATE() = 1
        begin 
            print N'Rollback Necessary' 
            rollback transaction
        end;
        throw 51000, N'There is an error with the application',1    

    end catch

end
GO

exec InsertProduct @ProductID = 1, @ProductName = 'B', @UnitPrice = 10.0, @UnitsInStock = 2, @UnitsOnOrder = 1

select * from Products

-- Generating an error
exec InsertProduct @ProductID = 1, @ProductName = 'C', @UnitPrice = 10.0, @UnitsInStock = 2, @UnitsOnOrder = 1

select * from Products

最后我收到了这个错误信息:

我的问题是,为什么这个函数的值是 1 而不是 -1,因为第二次插入对于违反主键定义是不可提交的。

【问题讨论】:

  • 在程序开始时将 XACT_ABORT 设置为 ON
  • 如果您想了解更多关于事务中的错误处理的信息,我强烈建议您研究一下 Erland Sommerskog 对此主题的看法:sommarskog.se/error_handling/Part1.html

标签: sql sql-server stored-procedures try-catch xact


【解决方案1】:

答案是一个

违反主键约束

错误不会导致无法提交的事务。约束阻止了插入的发生,因此事务实际上处于非常愉快的状态。

如果您希望该错误导致无法提交的事务,请在存储过程的开头添加;

SET XACT_ABORT ON;

这将确保所有错误都会导致无法提交的事务

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2011-09-21
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多