Answer the question
In order to leave comments, you need to log in
How to delay SELECT during INSERT when working with models in Laravel?
Greetings!
I ran into a problem while checking for the presence of a row in a table, when two read-write events fire almost at the same time.
In the body of the method, there is a check for "recent" records in the table, if there are none, then they can be inserted into the table. Then at the next check (an event from outside) the "recent" record will be found and a new INSERT will not occur.
But when two events occur within 50-150ms interval, the second SELECT check shows that there were no "recent" ones, because the first event is still being recorded (my guess). As a result of this, two lines are added.
The body of the method, where the check method is called and the insertion is:
$handle = new Handle;
$handle->date = Carbon::now();
$handle->oid = $id;
$next_id = Controller::getNextID();
if($next_id > 0)
$handle->save();
$handle = Handle::select(DB::raw("MAX(date) as date"))->where("oid", $id)->first(); // Найти последнюю дату записи
if($handle)
{
$date = Carbon::parse($handle->date)->addMinutes(15);
if($date < $now) // Если с момента последней записи прошло >15 минут
return $id; // $id всегда >0
}
return 0;
DB::beginTransaction();
stmt...
DB::commit();
Answer the question
In order to leave comments, you need to log in
Typical race condition. To fix, you need to find some place to serialize the transaction. The transaction is, of course, necessary. But some resource is also needed to serialize these transactions.
For example, by adding a suitable unique key (so that a competitive insert stumbles on it), advisory lock , serializable isolation level should not allow such a commit.
You wrap it in a transaction, inside you pull everything you want with the necessary locks (update lock, for example) and work with it.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question