需要在一个原子操作中更新 select
Need to update and select in one atomic operation
我正在编写代码来自动更正支付系统中的错误 - 在他们请求付款之前,他们会更新 [Table] 以获取处理付款所需的所有数据。如果成功,Status=1,如果失败,Status=0。
稍后,如果请求成功,它将重新处理任何状态为 0 的行。 (每个成功的请求只重新处理 1 个,以避免支付系统恢复在线后超载,但多个请求可能同时进入 SQL 服务器以获得失败的记录)
我有一个 table,有人告诉我要做这样的事情:
DECLARE @id int;
SET @id = (select top(1) id from [table] where Status = 0 order by id );
select * from [table] where id = @id;
update [table] set Success = NULL where id = @id;
但如果同时查询 运行,它们可能会得到相同的 @id 值,并且它们都会重新处理付款 - 创建重复项。
我正在考虑这样做:
DECLARE @id int;
DECLARE @tmp int;
SET @id = (select top(1) id from [table] where Success = 0 and RetryAttempCount < 5 order by id);
-- Code to handle multiple people hitting this at once. One will get -1, and the other -2
-- in the @tmp var.
update [table] set Success = Success -1, @tmp= Success -1 where id = @id;
if (@tmp = -1) -- then we got it
BEGIN
update [table] set RetryAttemptCount = RetryAttemptCount +1, RetryDate = GetDate(), Success = NULL
Where id=@id
select * from [table] where id = @id;
END
END
我的问题:有没有更好的方法?这似乎有效,返回需要重新处理的行,或者没有结果集。
如果操作的处理顺序无关紧要,为什么不这样做呢?
DECLARE @id int;
UPDATE TOP(1) [table] SET @id=id, Success=NULL WHERE Success=0 AND RetryAttemptCount<5;
我正在编写代码来自动更正支付系统中的错误 - 在他们请求付款之前,他们会更新 [Table] 以获取处理付款所需的所有数据。如果成功,Status=1,如果失败,Status=0。
稍后,如果请求成功,它将重新处理任何状态为 0 的行。 (每个成功的请求只重新处理 1 个,以避免支付系统恢复在线后超载,但多个请求可能同时进入 SQL 服务器以获得失败的记录)
我有一个 table,有人告诉我要做这样的事情:
DECLARE @id int;
SET @id = (select top(1) id from [table] where Status = 0 order by id );
select * from [table] where id = @id;
update [table] set Success = NULL where id = @id;
但如果同时查询 运行,它们可能会得到相同的 @id 值,并且它们都会重新处理付款 - 创建重复项。
我正在考虑这样做:
DECLARE @id int;
DECLARE @tmp int;
SET @id = (select top(1) id from [table] where Success = 0 and RetryAttempCount < 5 order by id);
-- Code to handle multiple people hitting this at once. One will get -1, and the other -2
-- in the @tmp var.
update [table] set Success = Success -1, @tmp= Success -1 where id = @id;
if (@tmp = -1) -- then we got it
BEGIN
update [table] set RetryAttemptCount = RetryAttemptCount +1, RetryDate = GetDate(), Success = NULL
Where id=@id
select * from [table] where id = @id;
END
END
我的问题:有没有更好的方法?这似乎有效,返回需要重新处理的行,或者没有结果集。
如果操作的处理顺序无关紧要,为什么不这样做呢?
DECLARE @id int;
UPDATE TOP(1) [table] SET @id=id, Success=NULL WHERE Success=0 AND RetryAttemptCount<5;