Метод lockForUpdate
Метод lockForUpdate применяется к запросу Query Builder или Eloquent и добавляет блокировку FOR UPDATE к SQL-запросу. Это означает, что выбранные строки блокируются для обновления другими транзакциями до тех пор, пока текущая транзакция не будет завершена (через commit или rollBack). Метод не принимает параметров и возвращает тот же экземпляр запроса с добавленной блокировкой. Используется исключительно внутри транзакций для обеспечения целостности данных при конкурентном доступе.
Синтаксис
<?php
DB::table($table)->lockForUpdate()->get();
?>
Пример
Давайте заблокируем запись пользователя с id равным 1 для последующего обновления внутри транзакции:
<?php
use App\Models\User;
use Illuminate\Support\Facades\DB;
DB::transaction(function () {
$user = User::where('id', 1)->lockForUpdate()->first();
if ($user) {
$user->balance -= 100;
$user->save();
}
});
?>
Результат выполнения кода:
"User balance updated successfully"
Пример
Заблокируем все активные заказы для массового обновления их статуса:
<?php
use App\Models\Order;
use Illuminate\Support\Facades\DB;
DB::transaction(function () {
$orders = Order::where('status', 'pending')
->lockForUpdate()
->get();
foreach ($orders as $order) {
$order->status = 'processing';
$order->save();
}
});
?>
Результат выполнения кода:
"All pending orders are locked and updated"
Пример
Используем метод lockForUpdate в комбинации с select для блокировки только определённых колонок:
<?php
use App\Models\Product;
use Illuminate\Support\Facades\DB;
DB::transaction(function () {
$products = Product::select('id', 'stock')
->where('stock', '>', 0)
->lockForUpdate()
->get();
foreach ($products as $product) {
$product->stock -= 1;
$product->save();
}
});
?>
Результат выполнения кода:
"Product stock decreased successfully"
Смотрите также
-
метод
sharedLock,
который устанавливает разделяемую блокировку -
метод
transaction,
который выполняет операции в транзакции -
метод
get,
который выполняет запрос и возвращает коллекцию -
метод
first,
который возвращает первую найденную запись