How do I prevent such a race condition from occuring? I understand that transactions in Laravel are blocking for updates, but how do I prevent stale data from being used? Is there a way to lock the database from reading while another transaction is going on? (i.e. have the second request wait for the first request to complete?)
Suppose username field in database for primary key id = 7 is null.
Request 1 comes in and does this:
public function raceCondition1() {
DB::beginTransaction();
//Get the model with primary key 7
$user = User::findorfail(7);
sleep(6);
$user->username = 'MyUsername';
$user->save();
DB::commit();
}
Two seconds later, I run Request 2, which just concatenates something to the username column and saves:
public function raceCondition2() {
DB::beginTransaction();
$user = User::findorfail(7);
sleep(6);
$user->username = 'USER_' . $user->username;
$user->save();
DB::commit();
}
The result in this case in the database is: USER_
The second request read from the database before the first request could save, and used the stale NULL value. Is there a way to lock the database from reading while another transaction is going on? (i.e. have the second request wait for the first request to complete?)