我有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)?
取决于隔离级别.在序列化中 – 是的,在较低级别,我几乎可以肯定,不.