行级锁定-MySQL-用于更新


Row Level Locking - MySQL - for update

我仍然对表行锁定感到困惑。我使用的是MySQL/PHP,下面是我的场景。

我有一组表,我的应用程序使用这些表来跟踪请求和帖子。用户为项目(表item(I))创建发布(表posting(P)),并可以向各个用户发送请求(表REQUEST(R)),或者可以发布并接收将由用户发布项目接受的发布响应(表POSPING_RESPONSE(PR))。

示例:我是一个骑自行车的用户。我发布它,并向个人用户发出请求。收到我请求的用户可以接受/拒绝/或什么都不做。如果他们接受,这是保留的。其他用户可以找到我的帖子并"申请"该项目。我有能力"接受"或"忽略"他们的请求。如果我接受,则保留项目。

如果有人接受请求,我想做什么:

  1. 锁定ITEM(I)表中与项目相对应的行

  2. 锁定POSTING(p)表中与项目对应的行(如果存在行)

  3. 锁定REQUEST(R)表中针对项目发送的任何请求的行

  4. 锁定POSTING_RESPONSE(PR)表中与项目对应的行(如果存在行)

  5. 将ITEM状态更新为"保留"

  6. 将张贴状态更新为"不可用"

  7. 将所有/任何POSTING_RESPONSE更新为"已拒绝"

  8. 将所有REQUEST更新为"Rejected"(已接受的请求除外)-将该请求更新为"accepted"

请忽略此示例中的状态冗余。

现在,我假设#1-4可以用一个类似的"select…for update"来完成,AUTOCOMMIT为false。我可以用这些select语句来决定是否应该更新——如果是,我可以继续更新。然后在更新#5-8完成后,我会提交并解锁行。

我在这方面遇到了问题,我不知道是因为我在做什么,还是我的想法不正确。

还有一件事。。。还有其他过程可以将项目的状态更新为,例如,EXPIRED或CANCELLED。我希望我的方法的唯一解决方案不是把每一个可能的条件都放在UPDATE语句中的WHERE子句中。。。这将不容易维护。

迷你事务:在一个查询中完成。

UPDATE item
LEFT JOIN posting
   ON posting.item_id = item.id -- or however
LEFT JOIN request 
   ON request.item_id = item.id -- or however
LEFT JOIN posting_reponse
   ON posting_response.item_id = item.id 
SET 
   item.status = 'Reserved',
   posting.status = 'Unavailable',
   posting_reponse.status = 'Rejected',
   request.status = IF(request.id = some-current-id,'Accepted','Rejected')
WHERE item.id = some-id AND item.status='Available';

停止询问有关锁定读取的问题,您真的不想这样:P