dqyin0101 2014-10-30 18:10
浏览 47
已采纳

行级锁定 - MySQL - 用于更新

I'm still confused about table row locking. I'm using MySQL/PHP and here is my scenario.

I have a set of tables that my application uses to keep track of requests and posts. A user creates a posting (table POSTING (P)) for an item (table ITEM (I)) and can send out requests to individual users (table REQUEST (R)) or can post it and receive post responses (table POSTING_RESPONSE (PR)) that will be accepted by user posting item.

Example: I am a user with a bike. I post it - and also send out requests to individual users. The users that receive the request from me can accept / reject / or do nothing. If they accept - it is reserved. Other users can find my posting and 'apply' for item. I have the ability to 'accept' or 'ignore' their request. If I accept, Item is reserved.

What I want to do if someone accepts request:

  1. lock row in ITEM (I) table corresponding to item

  2. lock row in POSTING (P) table (if row exists) corresponding to the item

  3. lock row(s) in REQUEST (R) table for any requests sent for item

  4. lock row(s) in POSTING_RESPONSE (PR) table (if rows exist) corresponding to item

  5. update ITEM status to 'Reserved'

  6. update POSTING status to 'Unavailable'

  7. update all/any POSTING_RESPONSE to 'Rejected'

  8. update all REQUEST to 'Rejected' besides the one that has accepted - update that one to 'Accepted'

Ignore the redundancy of status with this example please.

Now, I assumed that #1 - 4 could be done with a simiple "select ... for update" leaving AUTOCOMMIT as false. I could deterime with these select statements whether or not I should update - and if so, I can continue to the updates. Then after completion of updates #5-8, I would commit and rows would be unlocked.

I'm having problems getting this to work, and I don't know if it is because of something I'm doing or my thinking is incorrect.

One more thing... there are other processes that can update the status of the item to, say, EXPIRED or CANCELLED. I'm hoping that the only solution to my approach isn't to put every single possible condition in a WHERE clause within UPDATE statements... this would not be easily maintainable.

  • 写回答

1条回答 默认 最新

  • dtkvlj5386 2014-10-30 18:35
    关注

    Mini-transaction: do it in one query.

    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';
    

    ... and stop asking questions about locking for read, you really don't want that :P

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line