Таблица блокировки базы данных Laravel в параллельном запросе

Я хочу запретить обновление моей базы данных, если внезапно несколько запросов отправляются в мою базу данных и обновляются одновременно.

Я создаю пользовательскую таблицу пользователей Laravel в качестве примера и использую JMeter для симуляции двух пользователей, отправляющих параллельный запрос на изменение одной и той же строки данных.

Например, сценарий

Мой банковский счет имеет 1000 долларов. В то же время два запроса на перевод денег г-ну А и г-ну Б. отправляются с моего счета.

Мой счет для баланса — 1000, Запрос 1 — Отправьте 700 долларов США г-ну А. и Запрос 2 — Отправьте 700 долларов США мистеру Б. Если я не заблокировал стол, система будет обработана, у меня достаточно средств для отправки денег.

Моя цель заключается в том, что когда речь идет о параллельном запросе, второй (FIFO, даже если это параллельный веб-сервер все еще будет обрабатывать его и обрабатывать один из них как второй) бросить исключение / или показать ошибку возврата На запрос сказано, что он используется.

ниже приведен мой код для теста, и я использую JMeter для его запуска. Тем не менее, тест показывает, что оба запроса обновляются. Следовательно, последний запрос перезапишет первый запрос.

Ниже я ожидаю, что Laravel выдаст исключение или ошибку для блокировки базы данных, но она все еще продолжается.

Route::get('/db-a', function() {

\DB::beginTransaction();

//lock the table
$rs = \DB::table('users')->where('id', '1')->lockForUpdate()->first();

$sql = "update users set remember_token='this is a' where id=1";
\DB::update(DB::raw($sql));

//purposely put the sleep to see can the table / row be locked

sleep(3);

\DB::commit();

$rs = DB::table('users')->where('id', '1')->first();
echo($rs->remember_token);
return;
});

Route::get('/db-b', function () {

\DB::beginTransaction();

//lock the table
$rs = \DB::table('users')->where('id', '1')->lockForUpdate()->first();

$sql = "update users set remember_token='this is b' where id=1";
\DB::update(DB::raw($sql));

//purposely put the sleep to see can the table / row be locked
sleep(3);


\DB::commit();

$rs = DB::table('users')->where('id', '1')->first();
echo($rs->remember_token);
return;
});

Я делаю другую версию для ручного перехвата исключения, но тоже не работает

Route::get('db-callback-a', function() {
try {
app('db')->transaction(function () {
$record = \DB::table('users')->where('id', 1)->lockForUpdate()->first();
$sql = "update users set remember_token='this is callback a' where id=1";

\DB::update(DB::raw($sql));
sleep(3);
});
}
catch (\Exception $e) {
// display an error to user
echo('Database Row in Use, update later');
}
});

Route::get('db-callback-b', function () {
try {

app('db')->transaction(function () {
$record = \DB::table('users')->where('id', 1)->lockForUpdate()->first();
$sql = "update users set remember_token='this is callback b' where id=1";


\DB::update(DB::raw($sql));
sleep(3);
});
} catch (\Exception $e) {
// display an error to user
echo ('Database Row in Use, update later');
}
});

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]