mysql innodb事务并发

标签 mysql sql concurrency transactions innodb

我有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/

相关文章:

MySQL根据另一个表中的日期计算一个表中的行数

java - 如果我们想允许使用 putIFAbsent 覆盖 concuurentHashMap 中的值怎么办?

multithreading - 如何将父异步与多个子异步链接

sql - 如何在嵌套过程中找到父存储过程的 ID?

performance - SQLite 是否适合用作 Web 服务器上的只读缓存?

javascript - 如何将选定产品的行及其数量保存到 MySQL 数据库?

mysql - 如何使用缓存加速mysql查询

php - 用户已存在于数据库中 php 未显示消息

mysql - 处理请求错误代码 : 403 Error text: Forbidden 中的 Phpmyadmin MySQL 错误

sql - 在 PL/SQL 中的 With 子句之后使用 for 循环