我正在使用rowversion列来处理乐观并发,并希望在更新完成后获取新的rowversion值,以便我的数据层具有最新值,可以执行另一个更新操作,而不会出现并发异常(除非记录已被其他人更新)。
之前我在更新后在数据层进行了一次获取,但这不够高效或完全可靠。
对于下面的表:
CREATE TABLE PurchaseType
(
PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
Name nvarchar(50) NOT NULL,
TS rowversion NOT NULL
)
我尝试过:
CREATE PROCEDURE PurchaseType_UpdateWithGet
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT
AS
UPDATE PurchaseType
SET Name = @Name
WHERE PurchaseTypeCode = @PurchaseTypeCode
AND TS = @TS
SELECT @TS = TS FROM PurchaseType WHERE PurchaseTypeCode = @PurchaseTypeCode
GO
但我并不完全满意,因为存在无法从别人的更新中获取rowversion值的可能性。然后我在rowversion文档(http://msdn.microsoft.com/en-us/library/ms182776.aspx / http://msdn.microsoft.com/en-us/library/ms177564.aspx)中发现了OUTPUT语句,并尝试了以下操作:
CREATE PROCEDURE PurchaseType_UpdateWithOutput
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT
AS
DECLARE @Output TABLE (TS BINARY(8))
UPDATE PurchaseType
SET Name = @Name
OUTPUT inserted.TS into @Output
WHERE PurchaseTypeCode = @PurchaseTypeCode
AND TS = @TS
SELECT TOP 1 @TS = TS FROM @Output
GO
这个方法很有效。在我的基础测试中(只是运行了10000次调用并计时),使用OUTPUT选项需要的时间约长40%,但仍然少于半毫秒。在SET STATISTICS TIME ON下,两者都没有花费可测量的时间。
我的问题是,有没有人知道更好/更简单的方法来做到这一点?我希望能够使用类似于标识列的SCOPE_IDENTITY()函数的函数,但找不到类似的东西。有人知道我是否遗漏了什么吗?
提前感谢。
OUTPUT
将会失败。详见:https://dev59.com/qWYs5IYBdhLWcg3wBvb7。 - Ian Boyd