我有三张桌子:
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/