Ответ
Транзакция — это последовательность операций с базой данных, которая выполняется как единая, неделимая (атомарная) единица работы. Она гарантирует, что все операции либо будут успешно выполнены и зафиксированы (COMMIT), либо, в случае сбоя, полностью отменены (ROLLBACK), возвращая систему в исходное состояние.
Это обеспечивает целостность данных. Классический пример — банковский перевод: списание средств с одного счета и зачисление на другой должны произойти вместе или не произойти вовсе.
Основные свойства транзакций описываются акронимом ACID:
- Atomicity (Атомарность): Гарантирует, что транзакция выполняется по принципу "всё или ничего".
- Consistency (Согласованность): Транзакция переводит базу данных из одного согласованного состояния в другое. Все правила и ограничения (constraints) должны быть соблюдены.
- Isolation (Изолированность): Параллельно выполняющиеся транзакции не должны влиять друг на друга. Результат их одновременного выполнения должен быть таким же, как если бы они выполнялись последовательно.
- Durability (Долговечность): Если транзакция успешно завершена, ее результаты должны быть сохранены и не могут быть потеряны даже в случае сбоя системы (например, отключения питания).
Упрощенный пример на Python с sqlite3:
import sqlite3
# Используем 'with' для автоматического закрытия соединения
with sqlite3.connect('bank.db') as conn:
cursor = conn.cursor()
sender_id = 1
receiver_id = 2
amount = 100
try:
# Списание средств со счета отправителя
cursor.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (amount, sender_id))
# Зачисление средств на счет получателя
cursor.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (amount, receiver_id))
# Если обе операции успешны, фиксируем транзакцию
conn.commit()
print("Перевод успешно выполнен.")
except sqlite3.Error as e:
# При любой ошибке откатываем все изменения
conn.rollback()
print(f"Ошибка! Транзакция отменена: {e}") Ответ 18+ 🔞
А, ну вот, смотри, объясняю на пальцах, как для дебила, но ты не обижайся, я сам такой был. Транзакция — это, блядь, такая пачка операций, которую ты либо делаешь всю целиком, либо нихуя не делаешь. Как будто ты в магазине набрал продуктов, а на кассе карта не сработала. Так вот, либо ты всё оплатил и унёс, либо, сука, всё обратно на полки расставил и ушёл с пустыми руками. Никакого «половину купил, половину вернул» — нихуя!
Зачем это? Ну представь, ты переводишь бабки с карты на карту. Твои сто рублей списались, а у тётки на счёт нихуя не пришли. Где они? В небытии, в цифровом аду зависли. Вот чтобы такого пиздеца не было, и нужны транзакции. Либо списалось И зачислилось, либо нихуя не двигалось. Это и есть целостность, ёпта!
А теперь держись за стул, потому что есть такая хуйня под названием ACID. Это не кислота, а четыре буквы, которые спасают от ебалы.
- A — Атомарность (Atomicity). Это я уже объяснил. Всё или ничего. Как пиздец.
- C — Согласованность (Consistency). База данных — не помойка. В ней есть правила. «Баланс не может быть отрицательным», «ID должен быть уникальным». Так вот, транзакция обязана эти правила соблюсти. Не можешь — вали нахуй, откат.
- I — Изолированность (Isolation). Представь, что ты и твой кореш одновременно лезете в один и тот же ящик с деньгами. Начнётся драка, порвутся купюры. Изоляция — это когда вы лезете по очереди, или там ставят перегородки, чтобы вы друг другу не мешали. Результат должен быть такой, будто вы делали всё по одному, даже если делали впятером.
- D — Долговечность (Durability). Ну вот ты транзакцию сделал, деньги перевёл. И тут, блядь, свет вырубили, сервер упал. Так вот, когда его включат обратно, твой перевод должен быть там, записанный в каменную скрижаль, а не испарившийся, как твои надежды на повышение. Это и есть долговечность — закоммитил и забыл.
А вот тебе пример кода, чтобы вообще всё встало на свои места. Смотри, как это выглядит в жизни:
import sqlite3
# Используем 'with' для автоматического закрытия соединения
with sqlite3.connect('bank.db') as conn:
cursor = conn.cursor()
sender_id = 1
receiver_id = 2
amount = 100
try:
# Списание средств со счета отправителя
cursor.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (amount, sender_id))
# Зачисление средств на счет получателя
cursor.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (amount, receiver_id))
# Если обе операции успешны, фиксируем транзакцию
conn.commit()
print("Перевод успешно выполнен.")
except sqlite3.Error as e:
# При любой ошибке откатываем все изменения
conn.rollback()
print(f"Ошибка! Транзакция отменена: {e}")
Видишь? В try мы пытаемся сделать две штуки: списать и зачислить. Если где-то посередине случится пиздец (например, у отправителя денег нет), то мы летим в except и делаем rollback. И база откатывается назад, как будто мы нихуя и не начинали. А если всё прошло гладко — commit, и все изменения намертво прибиваются гвоздями. Вот и вся магия, ебать её в сраку.