При конкурентных изменениях данных важно исключить конфликты. Используем транзакции, блокировки строк и правильный уровень изоляции.
Создадим таблицу счетов:
CREATE TABLE Accounts (
id INT PRIMARY KEY,
name VARCHAR(50),
balance DECIMAL(10,2)
);
Начинаем транзакцию и блокируем строку:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- защита от грязных чтений
BEGIN;
SELECT balance FROM Accounts
WHERE id = 1 FOR UPDATE; -- эксклюзивная блокировка строки
Выполняем перевод и фиксируем результат:
UPDATE Accounts SET balance = balance - 500 WHERE id = 1;
UPDATE Accounts SET balance = balance + 500 WHERE id = 2;
COMMIT; -- сохраняем изменения
Откат транзакции:
ROLLBACK; -- можно вызвать до COMMIT при ошибке
🔥
FOR UPDATE ставит row-level exclusive lock: другие транзакции ждут, пока вы завершите свою.➡️ SQL Ready | #практика