首页 > 解决方案 > SQL:如果满足其他行的条件,则在并发情况下更新一行

问题描述

我正在并发情况下处理应用程序,其中应用程序的多个实例同时更新数据库中的行。每个应用程序实例在更新事件表中创建一个更新事件,一个更新事件的状态可以是 IN_PROGRESS/NEW/CANCELED。如果出现以下情况,我想创建一个查询来更新更新事件:

桌子:

UpdateId | itemId | status      | time_stamp
1        | 1      | IN_PROGRESS | 1.1
2        | 1      | NEW         | 1.2
3        | 1      | NEW         | 1.3
4        | 1      | NEW         | 1.4

对于上面的更新 1、2、3、4,基本上我希望 2 等到 1 完成,如果 3、4 来了,那么 2 -> 取消。对 3 也一样。

就像是:

Update UPDATE_EVENT SET status = IN_PROGRESS IF {
SELECT count (*) FROM UPDATE_EVENT where status=IN_PROGRESS & itemId=item1 = 0
  && 
 SELECT count (*) FROM UPDATE_EVENT where status=NEW & timestamp > updateId_abc123.timestamp = 0
} WHERE updateId=abc123

更新不是很频繁,延迟也不是问题。关于如何构建查询的任何想法以及它是否线程安全?

标签: mysqlconcurrencydatabase-administration

解决方案


主要问题是您在此过程中的频率和性能要求是什么。有捷径,也有很长的路。

很长的路需要您使用一个有序/单线程处理器来接收请求并将它们排队。使用流处理器和其他想法来控制这些请求。如果您在演出期间有大量更新,则使用流处理器可以很好地扩展。

对于较小的应用程序,可以检查并发隔离级别。并发使用一些锁定机制来确保第一个开始事务的人会完成它,并且只有在其他实例也能够进行更改之后。

两者都不是快速解决方案,需要您阅读一些有关它们的信息。如何在您的 SGBD、应用程序代码等中设置隔离级别。


推荐阅读