我有三张桌子:

Counters: ID, ItemCatalogID, CurrentCounter

Item: ID, ItemCatalogID, Name, Description, OtherValue

ItemCatalog: ID, Name, Description

Counters表包含一个项目目录的current counter,当我插入一行时,我必须查询DB,获取对应目录的当前计数器,然后将此值更新一个,并将此值用于OtherValue字段。
例如:
update Counters set CurrentCounter = CurrentCounter + 1 where ItemCatalogID = 100;
select CurrentCounter into v from Counters where ItemCatalogID = 100;
insert into Item(ItemCatalogID, Name, Description, OtherValue) values (100, 'MyItem', 'Short Description', v);

但我想知道种族状况会发生吗?如何改进我的解决方案?

最佳答案

是的,你的情况可能会引发种族问题。
你需要这些柜台吗?您可以轻松地用适当的查询替换它们:

SELECT COUNT(*) FROM ItemCatalog WHERE ID=100;
SELECT COUNT(*) FROM Item WHERE ID=100;

对于连续的字段内容,建议使用AUTO_INCREMENT列。但这似乎不适用于你的情况。
但是,您可以使用上面的COUNT(*)方法:
insert into Item(ItemCatalogID, Name, Description, OtherValue) values (100, 'MyItem', 'Short Description', (select count(*) from Item where ID=100));

可能需要将表中的某个实例命名为:
insert into Item(ItemCatalogID, Name, Description, OtherValue) values (100, 'MyItem', 'Short Description', (select count(*) from Item AS I where ID=100))

这只需一步执行,您就不必担心比赛条件了。
如果由于任何原因无法更改,则有另一种解决方案:使用表锁定。
在语句前加上前缀
LOCK TABLES Counters WRITE, Item WRITE

给他们加上后缀
UNLOCK TABLES

以便对它们具有独占的写访问权限。

关于mysql - 插入行时的竞争状况,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21201000/

10-13 03:02