【发布时间】:2018-08-21 16:38:52
【问题描述】:
我的存储过程中看似简单的部分似乎失败了,日期比较。我正在寻找超过 5 分钟的最早订单以开始处理。
python 程序调用存储过程来获取订单号并开始处理它。每次触摸订单都会修改o.chg_date,可能会延长 5 分钟的延迟。在订单创建过程中,有时销售人员会合并两个订单。他们需要这个 5 分钟的窗口来这样做。
这是存储过程的简化版本,但在其他 where 子句中是典型的。
CREATE PROCEDURE [dbo].[Get_Next_Order]
AS
SELECT TOP 1 o.order_id
FROM orders o (NOLOCK)
WHERE
o.order_state = 4 -- ready to be processed
AND o.order_status <> 3 -- not a deleted order
AND o.items > 0 -- not an empty order
AND o.chg_date < DATEADD(mi, -5, GETDATE()) -- 5 minute delay after ready
ORDER BY
o.chg_date
问题:在十几个订单中,两个将在 5 - 10 秒内得到处理。
我是否错误地使用了DATEADD 函数?它确实有 80% 的时间有效。而且我不能通过简单地在 SSMS 中运行代码来让它失败。
我能想到的唯一另一件事是,order_state = 4 和 chg_date 还没有更新。关于比赛条件解决的任何建议?
order_state 由代码更新。 chg_date 由触发器更新。
【问题讨论】:
-
-
正确。在 12:36 准备好的订单将需要再等一分钟才能处理。一旦处理完毕,order_state 将增加到 5。
-
我不确定你所说的“失败”是什么意思,当它“失败”时会发生什么?
-
历史文件显示,在 order_state 变为 = 4 后的 10 秒内,部分订单正在处理中,已被跟踪。这意味着 o.chg_date 比较失败,没有感觉到延迟。该订单不应该被处理。当我从 SP 中取出查询并在 SSMS 中运行时,它从来没有提出过没有完整 5 分钟延迟的订单。
-
我认为您有竞争条件,可能需要调查排他锁或其他方法。
标签: sql sql-server race-condition dateadd