Yes, your situation may likely provoque a race condition.
Do you need these counters at all? You can easily replace them with appropriate queries:
SELECT COUNT(*) FROM ItemCatalog WHERE ID=100;
SELECT COUNT(*) FROM Item WHERE ID=100;
For successive field contents it is advisable to use AUTO_INCREMENT
columns. But it seems that doesn't apply in your case.
But nevertheless, you can use the COUNT(*)
approach from above:
insert into Item(ItemCatalogID, Name, Description, OtherValue) values (100, 'MyItem', 'Short Description', (select count(*) from Item where ID=100));
It might be that you'll have to alias one of the occurrences of your table:
insert into Item(ItemCatalogID, Name, Description, OtherValue) values (100, 'MyItem', 'Short Description', (select count(*) from Item AS I where ID=100))
This executes in one step and you won't have to worry about a race condition.
If you cannot change this due to whatever reasons, there is another solution: use table locking.
Prefix your statements with
LOCK TABLES Counters WRITE, Item WRITE
and suffix them with
UNLOCK TABLES
in order to have exclusive write access to them.