mysql innodb事务并发

我有3张桌子

制品

PRODUCT_ID
max_products_can_sell
max_products_can_sell_to_individual

购买

用户身份
PRODUCT_ID
数量

预订

PRODUCT_ID
用户身份
数量

希望你理解结构.

现在,当用户试图购买产品时,我必须检查max_products_can_sell剩余的项目 – (保留的销售数量).

如果物品可用,我必须将其存储在预订表中,直到他购买为止. (将通过此表的cron作业保持住宅)

现在实际问题是,如何在这里处理并发问题.
例如:笔产品只有1个.两个用户请求reserve.php.

“a”用户请求reserve.php和可用笔是1.但在插入之前,对于“b”,用户可用的笔是1.所以两个用户保留笔.

我正在使用innodb表.怎么处理?

EIDT

  $query = SELECT count(*) as sold     FROM purchases WHERE product_id = 1;    
    $query = SELECT count(*) as reserved FROM reservations WHERE product_id = 1;     
    $items_remaining = $sold+$reserved;       

    if ($items_remaining) {      
       //INSERT data to reservations    
    } 

现在,我需要确保没有其他查询会干扰并执行相同的SELECT(在该连接完成更新行之前读取’旧值’.

正如Dan告诉我的那样,我可以通过LOCK TABLES表来确保一次只有一个连接正在执行此操作,并在完成后解锁它,但这看起来有点过分.在事务中包装它会做同样的事情(确保没有其他连接尝试相同的进程而另一个仍处理)?或者SELECT … FOR UPDATE或SELECT … LOCK IN SHARE MODE会更好吗?

我很困惑是使用事务还是锁定表或使用两者.请建议我..

EDIT2
在products表中,还有另一个名为max_can_sell_to_individual的字段.我必须检查当前库存,还必须检查个人限制.

我可以保持库存(库存可用),但我也要检查个别限制.这可以从购买表中找到.

请建议我如何处理它?

提前致谢!

最佳答案 我只会锁定产品记录(选择更新 – 注意,在共享模式下选择锁定不会阻止其他用户购买相同的产品),然后执行剩余的操作.通过这种方式,我不会阻止购买其他产品(锁定表将阻止任何写操作,无论是产品1还是产品2)

为什么要保留max_product_can_sell属性而不是(或不与)available_quantity属性一起?

As Dan told, I can LOCK TABLES table to just make sure that only 1 connection is doing this at a time, and unlock it when I’m done, but that seems like overkill. Would wrapping that in a transaction do the same thing (ensuring no other connection attempts the same process while another is still processing)?

取决于隔离级别.在序列化中 – 是的,在较低级别,我几乎可以肯定,不.

点赞