行级锁定 - MySQL - 用于更新

时间:2014-10-30 18:10:58

标签: php mysql mysqli innodb rowlocking

我仍然对表行锁定感到困惑。我正在使用MySQL / PHP,这是我的方案。

我有一组表,我的应用程序用它来跟踪请求和帖子。用户为项目(表格ITEM(I))创建发布(表POSTING(P))并且可以向单个用户发送请求(表REQUEST(R))或者可以发布它并接收发布响应(表POSTING_RESPONSE(PR) ))将被用户发布项目接受。

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

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

  1. 锁定与项目

  2. 对应的ITEM(I)表中的行
  3. 锁定POSTING(P)表中的行(如果存在行)对应于该项目

  4. 锁定REQUEST(R)表中的行以查找为项目发送的任何请求

  5. 在POSTING_RESPONSE(PR)表中锁定行(如果存在行)(对应于项目

  6. 将项目状态更新为“保留”

  7. 将POSTING状态更新为“Unavailable”

  8. 将所有/任何POSTING_RESPONSE更新为'已拒绝'

  9. 将所有请求更新为已拒绝的“已拒绝” - 将其更新为“已接受”

  10. 请使用此示例忽略状态冗余。

    现在,我认为#1 - 4可以使用simiple“select ... for update”来完成,而将AUTOCOMMIT保留为false。无论我是否应该更新,我都可以使用这些选择语句来确定 - 如果是,我可以继续更新。然后在完成更新#5-8后,我会提交并且行将被解锁。

    我在解决这个问题时遇到了问题,我不知道是因为我正在做的事情还是我的想法不正确。

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

1 个答案:

答案 0 :(得分:0)

迷你交易:在一次查询中完成。

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