Jos*_*ber 32 mysql concurrency if-statement insert race-condition
首先,这是问题的简明摘要:
INSERT有条件地运行声明是否可能?类似于此的东西:
IF(expression) INSERT...
Run Code Online (Sandbox Code Playgroud)
现在,我知道我可以使用存储过程执行此操作.我的问题是:我可以在查询中执行此操作吗?
现在,我为什么要这样做?
假设我们有以下2个表:
products: id, qty_on_hand
orders: id, product_id, qty
Run Code Online (Sandbox Code Playgroud)
现在,假设订购了20个Voodoo Dolls(产品ID 2).
我们首先检查手头的数量是否足够:
SELECT IF(
( SELECT SUM(qty) FROM orders WHERE product_id = 2 ) + 20
<=
( SELECT qty_on_hand FROM products WHERE id = 2)
, 'true', 'false');
Run Code Online (Sandbox Code Playgroud)
然后,如果它的计算结果为true,则运行INSERT查询.
到现在为止还挺好.
但是,并发性存在问题.
如果两个订单在同一时间进入,它们可能都会在其中任何一个订单进入订单之前读取手头数量.然后他们都会下订单,从而超过了qty_on_hand.
所以,回到问题的根源:
是否可以INSERT有条件地运行语句,以便我们可以将这两个查询合并为一个?
我搜索了很多,INSERT我能找到的唯一条件语句类型ON DUPLICATE KEY,这显然不适用于此.
Boh*_*ian 53
INSERT INTO TABLE
SELECT value_for_column1, value_for_column2, ...
FROM wherever
WHERE your_special_condition
Run Code Online (Sandbox Code Playgroud)
如果没有从select返回任何行(因为您的特殊条件为false),则不会发生插入.
使用您提出的架构(假设您的id列是auto_increment):
insert into orders (product_id, qty)
select 2, 20
where (SELECT qty_on_hand FROM products WHERE id = 2) > 20;
Run Code Online (Sandbox Code Playgroud)
如果手头库存不足,则不会插入任何行,否则将创建订单行.
不错的主意顺便说一下!
She*_*hef 19
尝试:
INSERT INTO orders(product_id, qty)
SELECT 2, 20 FROM products WHERE id = 2 AND qty_on_hand >= 20
Run Code Online (Sandbox Code Playgroud)
如果产品id等于2存在且该产品的qty_on_hand数量大于或等于20该产品,则会出现带有值的插入product_id = 2,和qty = 20.否则,不会发生插入.
注意:如果您的产品ID是note唯一的,则可能需要LIMIT在SELECT语句末尾添加一个子句.
| 归档时间: |
|
| 查看次数: |
69510 次 |
| 最近记录: |