Reputation: 135
I have a table COMMANDS
that users inserts data simultaneously.
After every insert I have to make some (time consuming) calculations and save the results to another table RESULTS
.
At time same time all users also reads data from COMMANDS
.
My question is :
After new $command
insert, I use all rows in that table in my calculations. Every row affects calculation and also may affect previous $commands
, because of that I want to lock this table for new inserts until current calculations are made and results are saved. But also I dont want to block other users to view current state of COMMANDS
.
Shortly I want to lock a table for writing without locking for reading.
I'am using InnoDB engine. I read some documents about locking, but i am totally confused.
Shared and exclusive locks, intention locks, gap locks ...
It seems stupid but currently I am using a mechanism like below
public function storeNewCommand($command){
// $busy_flag is an app level global that can be read by all user sessions
if($busy_flag){
usleep(10000);
return $this->storeNewCommand($command);
}
$busy_flag = true; //(lock)
/*
...insert new $command to COMMANDS
...do calculations using all comands including last one
...store results in RESULTS
*/
$busy_flag = false; //(unlock)
}
I know there must be better and clever solution for this without loops and sleeps. But I dont know which one to use.
Upvotes: 0
Views: 86
Reputation: 142503
If you can do the lengthy stuff in less than lock_wait_timeout
, which defaults to 50 seconds, then use BEGIN
...COMMIT
. (Personally, I would limit it to more like 2 seconds, not 50.)
Otherwise, devise some other method -- have a table that every writer honors that says that you are "busy" in this "critical section". It probably does not need to be much more than a 1- or 2-column table with a single row.
When grabbing that mutex, be sure to encapsulate the fetch, set, etc, in a transaction and react to failure. After getting the lock, then proceed to do the slow stuff. Finally release the lock.
Caveat: If there is a crash or a software bug, the code to release the lock may never be executed. So, it would be good to include a timestamp, plus something to notice that the mutex has not been released in a "long" time. It could them email you about the problem and clear the lock.
Upvotes: 1