我有3张 table
产品
产品编号
max_products_can_sell
max_products_can_sell_to_individual
购买
用户编号
产品编号
数量
预订
产品编号
用户编号
数量
希望您了解结构。
现在,当用户尝试购买产品时,我必须检查 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 表以确保一次只有 1 个连接正在执行此操作,并在我完成后将其解锁,但这似乎有点矫枉过正。将其包装在事务中会做同样的事情(确保没有其他连接尝试相同的过程而另一个仍在处理)?或者 SELECT ... FOR UPDATE 或 SELECT ... LOCK IN SHARE MODE 会更好吗?
我很困惑是使用事务还是锁定表,或者两者都使用。请建议我..
EDIT2
在产品表中,还有一个名为 max_can_sell_to_individual 的字段。我必须检查当前库存,还必须检查个人限额。
我可以维护库存(有库存),但我还必须检查个人限额。这可以从采购表中找到。
请建议我该如何处理?
提前致谢!
最佳答案
我只会锁定产品记录(使用select for update - 注意,在共享模式下选择锁定不会阻止其他用户购买相同的产品),然后执行其余操作.这样我就不会阻止购买其他产品(而锁定表将阻止任何写操作,无论是否有产品 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)?
取决于隔离级别。在可序列化中 - 是的,在较低级别,我几乎可以肯定,不。
关于mysql innodb事务并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6914122/