Ответ
Да, операция UPDATE по умолчанию является транзакционной в контексте СУБД.
Ключевые моменты:
- Часть транзакции: Любая DML-операция (
INSERT,UPDATE,DELETE) выполняется внутри транзакции — явной или неявной. - Соблюдение ACID:
UPDATEподчиняется свойствам транзакций:- Атомарность (Atomicity): Изменения либо применяются все (
COMMIT), либо откатываются все (ROLLBACK). - Согласованность (Consistency):
UPDATEпереводит базу из одного согласованного состояния в другое (с учетом ограничений). - Изолированность (Isolation): Параллельные
UPDATEк одним строкам управляются уровнями изоляции. - Долговечность (Durability): После
COMMITизменения фиксируются.
- Атомарность (Atomicity): Изменения либо применяются все (
Пример транзакции с UPDATE:
START TRANSACTION; -- Начало явной транзакции
UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100.00 WHERE user_id = 2;
-- Оба UPDATE являются частью одной атомарной операции перевода.
COMMIT; -- Фиксация изменений
-- или ROLLBACK; -- Откат обоих UPDATE в случае ошибки
Важно: В режиме AUTOCOMMIT=ON (по умолчанию в многих клиентах) каждый отдельный UPDATE представляет собой однооперационную транзакцию, которая автоматически фиксируется.
Ответ 18+ 🔞
А, вот ты про транзакции, да? Ну, слушай, сейчас разжуём, как же этот UPDATE там внутри работает, блядь.
Короче, да, любая операция, которая меняет данные — INSERT, UPDATE, DELETE — она по жизни всегда в транзакции сидит. Как таракан в щели, блядь. Либо ты её сам в свою, явную, засунул, либо СУБД её для тебя в одноразовую, неявную, завернёт. Без вариантов.
И работает это всё по правилам, которые называются ACID, ну, как свод законов для бухгалтерии, только для данных, ёпта.
Смотри, что происходит, когда ты пишешь UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1;:
-
Атомарность (Atomicity). Это как принцип "всё или ничего", блядь. Или деньги с одного счёта списались и на другой зачислились, или нихуя не произошло. Никаких промежуточных состояний, типа "списалось, но не дошло". Либо коммит, либо откат в пизду. Как в игре "испорченный телефон", только здесь либо сообщение дошло целиком, либо его сожрали крысы.
-
Согласованность (Consistency). База не должна сойти с ума после твоего апдейта. Если на счёте было 50 рублей, а ты пытаешься списать 100, то, блядь, ограничение (
CHECKили триггер) должно встать поперёк горла этой операции и сказать: "Нихуя, мудила, у него тут только полтинник!". И транзакция откатится. Чтобы баланс не ушёл в минус, как репутация после пьянки. -
Изолированность (Isolation). А вот это, сука, самая интересная часть, где начинаются все эти гонки и геморрои. Представь, что два процесса одновременно лезут обновлять одну и ту же строку. Один пишет "баланс = 100", другой — "баланс = 200". Кто победит? А хуй его знает! Для этого и есть уровни изоляции — чтобы решать, кто кого и когда должен видеть. Без них был бы пиздец и бардак, как в общаге в субботу.
-
Долговечность (Durability). Это когда ты уже сделал
COMMIT, выпил чаю, и тут бах — свет отрубили. А после включения твои изменения на месте, блядь. Они не испарились, их не сожрали белки. Они тупо записаны на диск, и всё. Как высеченные в камне, только в цифре.
Теперь про авто-коммит. Это, блядь, такой режим по умолчанию, когда ты каждый свой чих — прости, каждый свой UPDATE — СУБД сама заворачивает в отдельную, маленькую транзакцию и сразу же фиксирует. Удобно для простых операций, но для связных вещей — полный пиздец. Представь перевод денег:
-- А вот так делать — это путь в ад, блядь. При AUTOCOMMIT=ON:
UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1; -- Сразу закоммитилось! Опа!
-- *здесь сервер падает*
UPDATE accounts SET balance = balance + 100.00 WHERE user_id = 2; -- Уже не выполнится.
-- Итог: 100 рублей испарились в никуда. Магия, сука!
Поэтому для серьёзных дел нужно явно говорить: "Так, стопэ, машина, сейчас будет группа операций, не дёргайся".
START TRANSACTION; -- Всё, понеслась, блядь. Начали пакет.
UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100.00 WHERE user_id = 2;
-- Пока ничего не зафиксировано. Всё в подвешенном состоянии.
-- Проверяем, что всё ок, ошибок нет...
COMMIT; -- Вот теперь да, хуяк — и оба изменения разом применились. Красота.
-- Или, если что-то пошло не так:
-- ROLLBACK; -- И похуй, откатываем всё к чёртовой матери. Как будто ничего и не было.
Так что да, UPDATE — он всегда транзакционный. Просто иногда эта транзакция — короткая и невидимая, как поход в туалет в гостях, а иногда — большая и сложная, как генеральная уборка с выносом хлама. Главное — понимать, в какой момент ты находишься, а то можно и насрать мимо цели, блядь.