我有一个Postgres(9.5)DB,用于由Web和后台工作进程组成的应用程序。
如果我们收到HTTP请求POST /items/123/steps
,那么Web应用程序将对后台任务进行排队,以对项目123执行“工作流程步骤”并返回。该项对应于Postgres items
表中的一行,并且具有id值为123的列。
目标是以某种方式锁定项目123以进行处理,以便后续请求POST /items/123/steps
将被拒绝,直到后台任务在完成其工作后解锁项目123。
同样,对GET /items/123
的请求必须返回一个属性,指示项目123已被锁定,以便UI可以将项目显示为当前正在处理,直到后台任务解锁它。
因为在从队列中拾取后台任务之前可能会有延迟,所以后台任务在开始执行时锁定项目123是不够的。我希望将项目123从初始POST
Web请求标记为已锁定,直到后台任务完成,以便在拾取后台任务之前,该项目显示为已锁定的任何Web请求。
如果可能的话,我想使用Postgres来实现这一目标。然而,我发现的选项似乎不起作用:
SELECT FOR UPDATE
。我可以通过实施临时锁定机制来解决这个问题:将locked
列添加到items
并在网络端点中将其设置为TRUE
,然后再返回{{ 1}}在后台任务中。如果我更愿意采用更标准的方法,那么我宁愿这样做。
其他信息:这是一个Python项目,我正在使用SQLAlchemy从(Flask)Web应用程序和(Celery)后台任务访问Postgres。如果有另一种经过验证的方法可以使用这些适用于我的工具来实现目标。
答案 0 :(得分:1)
使用locked
列的“解决方法”实际上是正确的解决方案。
正如您所正确观察的那样,定期锁定和咨询都不能很好地适应您的情况。