锁定表和/或库存表的交易?

时间:2017-11-13 03:52:34

标签: mysql concurrency transactions locking innodb

如何使用InnoDB维护库存表的数据完整性?这是否需要使用表锁和事务?我试图找到一些很好的例子,但即使是众所周知的开源电子商务软件也没有实现表锁/事务。下面的代码会工作吗?我真的需要锁定整个桌子,还是只能锁定销售产品的行?或者有没有人有一个很好的例子?

CREATE TABLE `stock` (
    `product_id` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0',
    PRIMARY KEY (`product_id`)
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB;

LOCK TABLES stock WRITE;
START TRANSACTION;
SET autocommit = 0;
UPDATE stock SET quantity = quantity - 4 WHERE product_id = 'PRODUCT_1' AND quantity >= 4;
UPDATE stock SET quantity = quantity - 2 WHERE product_id = 'PRODUCT_2' AND quantity >= 2;
UPDATE stock SET quantity = quantity - 5 WHERE product_id = 'PRODUCT_3' AND quantity >= 5;
COMMIT or ROLLBACK;

如果所有UPDATE查询都有1个受影响的行,则返回COMMIT,否则返回ROLLBACK

2 个答案:

答案 0 :(得分:0)

除非您要确保运行相同代码的并发客户端不运行同步更新,否则不必执行表锁定。我不确定这一点很重要,因为每个更新都在处理不同的行子集。

在任何情况下,启动事务后都不必设置autocommit = 0。隐式启动事务意味着在使用COMMIT(或某些语句导致隐式提交)之前它不会提交。

您甚至可以将所有三个更新包装到一个更新中,除非您说要确保每个更新至少更改一行。

答案 1 :(得分:0)

" 1受影响的行"不是经过测试的。测试失败,死锁,超时等。如果你想要失败,如果它不是每行1行,那么你需要获取rows_affected,测试" 1",然后ROLLBACK或不。{/ p>

另外,

COMMIT or ROLLBACK

需要"如果......然后ROLLBACK else COMMIT"。最好用您的应用程序语言完成。