Транзакции и механизмы их контроля / Хабр
Транзакции
Транзакцией называется последовательность операций над данными имеющая начало и конец
Транзакция это последовательное выполнение операций чтения и записи. Окончанием транзакции может быть либо сохранение изменений (фиксация, commit) либо отмена изменений (откат, rollback). Применительно к БД транзакция это нескольких запросов, которые трактуются как единый запрос.
Транзакции должны удовлетворять свойствам ACID
Атомарность. Транзакция либо выполняется полностью либо не выполняется вовсе.
Согласованность. При завершении транзакции не должны быть нарушены ограничения накладываемые на данные (например constraints в БД). Согласованность подразумевает, что система будет переведена из одного корректного состояния в другое корректное.
Изолированность. Параллельно выполняемые транзакции не должны влиять друг на друга, например менять данные которые использует другая транзакция. Результат выполнения параллельных транзакций должен быть таким, как если бы транзакции выполнялись последовательно.
Устойчивость. После фиксации изменения не должны быть утеряны.
Журнал транзакций
Журнал хранит изменения выполненные транзакциями, обеспечивает атомарность и устойчивость данных в случае сбоя системы
Простое повторное выполнение ошибочных транзакций недостаточно для восстановления.
Пример. На счету у пользователя 500$ и пользователь решает снять их через банкомат. Выполняются две транзакции. Первая читает значение баланса и если на балансе достаточно средств выдает деньги пользователю. Вторая вычитает из баланса нужную сумму. Допустим, произошел сбой системы и первая операция не выполнилась, а вторая выполнилась. В этом случае мы не можем повторно выдать деньги пользователю без возврата системы в изначальное состояние с положительным балансом.
Уровни изоляции
Чтение фиксированных данных (Read Committed)
Проблема грязного чтения (Dirty Read) заключается в том, что транзакция может прочесть промежуточный результат работы другой транзакции.
Пример. Начальное значение баланса 0$. Т1 добавляет к балансу 50$. Т2 считывает значение баланса (50$). Т1 отменяет изменения и завершается. T2 продолжает выполнение располагая неверными данными о балансе.
Решением является чтение фиксированных данных (Read Committed) запрещающее читать данные, измененные транзакцией. Если транзакция A изменила некоторый набор данных, то транзакция B при обращении за этими данными вынуждена ожидать завершения транзакции A.
Повторяемое чтение (Repeatable Read)
Проблема потерянных изменений (Lost Updates). Т1 сохраняет изменения поверх изменений Т2.
Пример. Начальное значение баланса 0$ и две транзакции одновременно пополняют баланс. T1 и T2 читают баланс равный 0$. Затем T2 прибавляет 200$ к 0$ и сохраняет результат. T1 прибавляет 100$ к 0$ и сохраняет результат. Итоговый результат 100$ вместо 300$.
Проблема неповторяемого чтения (Unrepeatable read). Повторное чтение одних и тех же данных возвращает разные значения.
Пример. Т1 читает значение баланса равное 0$. Затем Т2 добавляет к балансу 50$ и завершается. Т1 повторно читает данные и обнаруживает несоответствие с предыдущим результатом.
Повторяемое чтение (Repeatable Read) гарантирует что повторное чтение вернет тот же результат. Данные прочитанные одной транзакцией запрещено менять в других до завершения транзакции. Если транзакция A прочла некоторый набор данных, то транзакция B при обращении за этими данными вынуждена ожидать завершения транзакции A.
Упорядоченное чтение (Serializable)
Проблема фантомного чтения (Phantom Reads). Два запроса выбирающие данные по некоему условию возвращают разные значения.
Пример. T1 запрашивает количество всех пользователей баланс которых больше 0$ но меньше 100$. T2 вычитает 1$ у пользователя с балансом 101$. T1 повторно выполняет запрос.
Упорядоченное чтение (Serializable). Транзакции выполняются как полностью последовательные. Запрещается обновлять и добавлять записи, подпадающие под условия запроса. Если транзакция A запросила данные всей таблицы, то таблица целиком замораживается для остальных транзакций до завершения транзакции A.
Планировщик (Scheduler)
Устанавливает очередность в которой должны выполняться операции при параллельно протекающих транзакциях
Обеспечивает заданный уровень изолированности. Если результат выполнения операций не зависит от их очередности, то такие операции коммутативны (Permutable). Коммутативны операции чтения и операции над разными данными. Операции чтения-записи и записи-записи не коммутативны. Задача планировщика чередовать операции выполняемые параллельными транзакциями так, чтобы результат выполнения был эквивалентен последовательному выполнению транзакций.
Механизмы контроля параллельных заданий (Concurrency Control)
Оптимистический основан на обнаружении и разрешении конфликтов, пессимистический на предотвращении возникновения конфликтов
При оптимистическом подходе несколько пользователей получают в свое распоряжение копии данных. Первый завершивший редактирование сохраняет изменения, остальные же должны осуществить слияние изменений. Оптимистический алгоритм позволяет конфликту произойти, но система должна восстановиться после конфликта.
При пессимистическом подходе первый пользователь захвативший данные препятствует получению данных остальным. Если конфликты редки разумно выбрать оптимистическую стратегию, так как она обеспечивает более высокий уровень параллелизма.
Блокировка (Locking)
Если одна транзакция заблокировала данные, то остальные транзакции при обращении к данным обязаны ждать разблокировки
Блок может накладываться на базу данных, таблицу, ряд или аттрибут. Совместный захват (Shared Lock) может быть наложен на одни данные несколькими транзакциями, разрешает всем транзакциям (включая наложившую) чтение, запрещает изменение и монопольный захват. Монопольный захват (Exclusive Lock) может быть наложен только одной транзакцией, разрешает любые действия наложившей транзакции, запрещает любые действия остальным.
Взаимоблокировкой считается ситуация когда транзакции оказываются в режиме ожидания, длящемся бесконечно долго
Пример. Первая транзакция ждет освобождения данных захваченных второй, в то время как вторая ждет освобождения данных, захваченных первой.
Оптимистическое решение проблемы взаимоблокировок позволяет взаимоблокировке произойти, но затем восстанавливает систему откатывая одну из транзакций, участвующих во взаимоблокировке
С определенной периодичностью производится поиск взаимоблокировок. Один из способов обнаружения — по времени, то есть считать что взаимоблокировка произошла если транзакция выполняется слишком долго. Когда взаимоблокировка найдена, то одна из транзакций откатывается, что дает возможность другим транзакциям участвующим во взаимоблокировке завершиться. Выбор жертвы может быть основан на стоимости транзакций или их старшинстве (Wait-Die и Wound-wait схемы).Каждой транзакции T присваивается временная метка TS содержащая время начала выполнения транзакции.
Wait-Die.
Если TS(Ti) < TS(Tj), то Ti ждет, иначе Ti откатывается и начинается заново с той же временной меткой.
Если молодая транзакция захватила ресурс, а более старая запрашивает тот же ресурс, то старшей транзакции позволено ожидать. Если более старая транзакция захватила ресурс, то молодая транзакция запрашивающая этот ресурс будет откачена.
Wound-wait.
Если TS(Ti) < TS(Tj), то Tj откатывается и начинается заново с той же временной меткой, иначе Ti ждет.
Если более молодая транзакция захватила ресурс, а более старая транзакция запрашивает этот же ресурс, то молодая транзакция будет откачена. Если более старая транзакция захватила ресурс, то более молодой транзакции, запрашивающей этот ресурс позволено ожидать. Выбор жертвы основанный на старшинстве предотвращает появление взаимоблокировок, но откатывает транзакции которые не находятся в состоянии взаиомблокировки. Проблема заключается в том, что транзакции могут откатываться много раз, т.к. более старая транзакция может долго удерживать ресурс.
Пессимистическое решение проблемы взаимоблокировок не позволяет транзакции начать выполнение если есть риск возникновения взаимоблокировки
Для обнаружения взаимоблокировки строится граф (граф ожидания, wait-for-graph), вершины которого транзакции, а ребра направлены от транзакций ожидающих освобождения данных к транзакции захватившим эти данные. Считается что взаимоблокировка произошла, если граф имеет зацикленность. Построение графа ожидания, особенно в распределенных БД, дорогостоящая процедура.
Двухфазная блокировка — предотвращение взаимоблокировок путем захвата всех ресурсов используемых транзакцией в начале транзакции и освобождения их в конце
Все блокирующие операции должны предшествовать первой разблокирующей. Имеет две фазы — Growing Phase при которой происходит накопление захватов и Shrinking Phase при которой происходит освобождение захватов. При невозможности захвата одного из ресурсов транзакция начинается сначала. Возможна ситуация когда транзакция не сможет захватить требуемые ресурсы, например если несколько транзакций будут конкурировать за одни ресурсы.
Двухфазный коммит обеспечивает выполнение коммита на всех репликах БД
Каждая БД вносит информацию о данных которые будут изменены в лог и отвечает координатору ОК (Voting Phase). После того как все ответили ОК координатор отсылает сигнал обязывающий всех произвести коммит. После коммита сервера отвечают ОК, если хоть один не ответил ОК, то координатор отсылает сигнал отмены изменений всем серверам (Completion Phase).
Метод временных меток
Более старая транзакция откатывается при попытке доступа к данным, задействованным более молодой транзакцией
Каждой транзакции назначается временная метка
TSсоответствующая времени начала выполнения. Если
старше
Tj, то
TS(Ti)TS(Tj).
Когда транзакция откатывается, ей назначается новая временная метка. Каждый объект данных Q задействованный транзакцией помечается двумя метками. W-TS(Q) — временная метка самой молодой транзакции, успешно выполнившей запись над Q. R-TS(Q) — временная метка самой молодой транзакции, выполнившей запись чтения над Q.
Когда транзакция T запрашивает чтение данных Q возможны два варианта.
Если TS(T) < W-TS(Q), то есть данные были обновлены более молодой транзакцией, то транзакция T откатывается.
Если TS(T) >= W-TS(Q), то чтение выполняется и R-TS(Q) становится MAX(R-TS(Q), TS(T)).
Когда транзакция T запрашивает изменение данных Q возможны два варианта.
Если TS(T) < R-TS(Q), то есть данные уже были прочитаны более молодой транзакцией и если произвести изменение, то возникнет конфликт. Транзакция T откатывается.
Если TS(T) < W-TS(Q), то есть транзакция пытается перезаписать более новое значение, транзакция T откатывается. В остальных случаях изменение выполняется и W-TS(Q) становится равным TS(T).
Не требуется дорогостоящего построения графа ожидания. Более старые транзакции зависят от более новых, следовательно в графе ожидания нет циклов. Нет взаимоблокировок, поскольку транзакции не ожидают, а сразу откатываются. Возможны каскадные откаты. Если Ti откатилась, а Tj прочитала данные которые изменила Ti, то Tj тоже должна откатиться. Если при этом Tj уже была закоммичена, то возникнет нарушения принципа устойчивости.
Одно из решений каскадных откатов. Транзакция выполняет все операции записи в конце, причем остальные транзакции обязаны ожидать завершения этой операции. Транзакции ожидают коммита перед чтением.
Thomas write rule — вариация метода временных меток при которой данные обновленные более молодой транзакцией запрещено перезаписывать более старой
Транзакция
Tзапрашивает изменение данных
Q. Если
TS(T)W-TS(Q), то есть транзакция пытается перезаписать более новое значение, транзакция T не откатывается как в методе временных меток.
Руководство по SQL. Транзакции. – PROSELYTE
Транзакция является рабочей единицей работы с базой данных (далее – БД). Это последовательность операций, выполняемых в логическом порядке пользователем, либо программой, которая работает с БД.
Мы можем сказать, что транзакция – это распространение изменений в БД. Например, если мы создаём, изменяем или удаляем запись, то мы выполняем транзакцию. Крайне важно контролировать транзакции для гарантирования.
Основные концепции транзакции описываются аббревиатурой ACID – Atomicity, Consistency, Isolation, Durability (Атомарность, Согласованность, Изолированность, Долговечность).
Атомарность
Атомарность гарантирует, что любая транзакция будет зафиксирована только целиком (полностью). Если одна из операций в последовательности не будет выполнена, то вся транзакция будет отменена. Тут вводится понятие “отката” (rollback). Т.е. внутри последовательности будут происходить определённые изменения, но по итогу все они будут отменены (“откачены”) и по итогу пользователь не увидит никаких изменений.
Согласованность
Это означает, что любая завершённая транзакция (транзакция, которая достигла завершения транзакции – end of transaction) фиксирует только допустимые результаты. Например, при переводе денег с одного счёта на другой, в случае, если деньги ушли с одного счёта, они должны прийти на другой (это и есть согласованность системы). Списание и зачисление – это две разные транзакции, поэтому первая транзакция пройдёт без ошибок, а второй просто не будет. Именно поэтому крайне важно учитывать это свойство и поддерживать баланс системы.
Изолированность
Каждая транзакция должна быть изолирована от других, т.е. её результат не должен зависеть от выполнения других параллельных транзакций. На практике, изолированность крайне труднодостижимая вещь, поэтому здесь вводится понятие “уровни изолированности” (транзакция изолируется не полностью).
Долговечность
Эта концепция гарантирует, что если мы получили подтверждение о выполнении транзакции, то изменения, вызванные этой транзакцией не должны быть отменены из-за сбоя системы (например, отключение электропитания).
Управление транзакциями
Для управления транзакциями используются следующие команды:
- COMMIT
Сохраняет изменения - ROLLBACK
Откатывает (отменяет) изменения - SAVEPOINT
Создаёт точку к которой группа транзакций может откатиться - SET TRANSACTION
Размещает имя транзакции.
Команды управление транзакциями используются только для DML команд: INSERT, UPDATE, DELETE. Они не могут быть использованы во время создания, изменения или удаления таблицы.
Примеры:
Перед началом выполните следующую команду, для того, чтобы отключить автоматическое выполнение транзакции:
mysql> SET autocommit=0;
Предположим, что у нас есть таблица developers, которая содержит следующие записи:
+----+-------------------+-----------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+-----------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 3 | Andrei Komarov | C++ | 3 | 2500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
| 5 | Asya Suleimanova | UI/UX | 2 | 1800 |
| 7 | Ivan Ivanov | C# | 1 | 900 |
| 8 | Ludmila Geiko | UI/UX | 2 | 1800 |
+----+-------------------+-----------+------------+--------+
Удалим всех С++ разработчиков с помощью следующей команды:
mysql> DELETE FROM developers
WHERE SPECIALTY = 'C++';
mysql> COMMIT;
В результате выполнения данного запроса наша таблица будет содержать следующие записи:
+----+-------------------+-----------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+-----------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
| 5 | Asya Suleimanova | UI/UX | 2 | 1800 |
| 7 | Ivan Ivanov | C# | 1 | 900 |
| 8 | Ludmila Geiko | UI/UX | 2 | 1800 |
+----+-------------------+-----------+------------+--------+
Теперь попробуем выполнить команду ROLLBACK:
mysql> ROLLBACK;
После выполнения данной команды наша таблица содержит следующие данные:
+----+-------------------+-----------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+-----------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 3 | Andrei Komarov | C++ | 3 | 2500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
| 5 | Asya Suleimanova | UI/UX | 2 | 1800 |
| 6 | Ludmila Geiko | UI/UX | 2 | 1800 |
| 7 | Ivan Ivanov | C# | 1 | 900 |
+----+-------------------+-----------+------------+--------+
Как мы видим, запись С++ разработчика вновь в таблице.
Теперь постараемся разобраться с SAVEPOINT.
Для начала создадим точку сохранения, используя следующий запрос:
mysql> SAVEPOINT SP1;
Теперь выполним следующие запросы:
mysql> DELETE FROM developers WHERE ID = 7;
Query OK, 1 row affected (0.00 sec)
mysql> DELETE FROM developers WHERE ID = 6;
Query OK, 1 row affected (0.02 sec)
mysql> DELETE FROM developers WHERE ID = 5;
Query OK, 1 row affected (0.00 sec)
На данный момент наша таблица содержит следующие записи:
+----+-------------------+-----------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+-----------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 3 | Andrei Komarov | C++ | 3 | 2500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
+----+-------------------+-----------+------------+--------+
Теперь мы вернёмся к точке сохранения SP1 с помощью команды:
mysql> ROLLBACK TO SP1;
После выполнения данного запроса, наша таблица будет хранить следующие записи:
+----+-------------------+-----------+------------+--------+
| ID | NAME | SPECIALTY | EXPERIENCE | SALARY |
+----+-------------------+-----------+------------+--------+
| 1 | Eugene Suleimanov | Java | 2 | 2500 |
| 2 | Peter Romanenko | Java | 3 | 3500 |
| 3 | Andrei Komarov | C++ | 3 | 2500 |
| 4 | Konstantin Geiko | C# | 2 | 2000 |
| 5 | Asya Suleimanova | UI/UX | 2 | 1800 |
| 6 | Ludmila Geiko | UI/UX | 2 | 1800 |
| 7 | Ivan Ivanov | C# | 1 | 900 |
+----+-------------------+-----------+------------+--------+
Как мы видим, мы откатились к состоянию таблицы на момент создания точки сохранения SP1.
Теперь, когда нам больше не нужна данная точка сохранения, мы можем её освободить:
mysql> RELEASE SAVEPOINT SP1;
В завершение мы рассмотрим команду SET TRANSACTION, которая используется для того, чтобы инициировать транзакцию БД. Данная команда, позволяет нам определить характеристики транзакции.
Например, если мы хотим, указать, что транзакция предназначена только для чтения, то мы должны использовать следующий запрос:
SET TRANSACTION READ ONLY;
Если же мы хотим, чтобы транзакция позволяла выполнять запись данных, то запрос будет иметь вид, указанный ниже:
SET TRANSACTION READ WRITE;
На этом мы заканчиваем изучение SQL транзакций.
В следующей статье мы рассмотрим функции даты.
Состояния транзакций, сборка мусора, интересующиеся и активные транзакции, sweep, примеры
Автор: Ann Harrison, Harbor
Перевод: Дмитрий Кузьменко
Оригинальный текст: oitoat.txt
Внимание! Документ устарел, и хотя и содержит верные сведения, к прочтению не рекомендуется. Вместо него следует читать более современные и подробные статьи:
Пояснение для новичков – когда я говорю «транзакция», я имею в виду набор действий над базой данных, завершающихся Commit (подтверждением), Rollback (отменой), Prepare/Commit (подготовкой к подтверждению при two phase commit), и в том числе отсоединением от базы данных (обрыв связи, выключение клиентского компьютера и т. п.). Простое действие, как вставка, изменение или удаление записи, является оператором. Многие инструменты обеспечивают автоматическую поддержку транзакций, поэтому вам может быть неизвестно реальное количество транзакций, выполняемых при работе с данными. Но любой инструмент, производящий подтверждение (commit) на каждый оператор, не является лучшим выбором при импорте данных в БД.
Состояния транзакций
Транзакции могут находиться в четырех состояниях: активном, подтвержденном, limbo (подтвержденное но не зафиксированное по TPC) и отмененном.Рассмотрим каждое состояние подробнее от самого сложного до самого простого:
Limbo: Транзакция, стартовавшая в режиме 2PC (two phase commit) вызовом процедуры Prepare. Эта транзакция может быть живой или нет. В любой момент такая транзакция может возобновиться и запросить подтверждение или отмену. Изменения, произведенные транзакцией, оставшейся в состоянии in limbo не могут быть приняты или игнорированы, соответственно они не могут быть удалены из БД.
Подтвержденное: Транзакция, которая завершила всю свою работу успешно
- вызовом процедуры COMMIT
- вызовом процедуры Rollback, но не произведя никаких изменений в БД.
Отмененное: Транзакция, которая
- завершилась процедурой ROLLBACK, т. е. запросила удалить все произведенные ею изменения из БД.
- была помечена как Активная, но была обнаружена в неживом состоянии другой транзакцией, которая и помечает ее как отмененную.
Активное: Такое состояние имеет транзакция, которая
- не стартовала.
- стартовала, но еще не завершилась.
- стартовала, но не закончилась вызовом любой процедуры завершения. (Например, из-за сбоя питания, обрыва соединения и т. п.)
Как транзакции узнают о состояниях друг друга?
Состояние каждой транзакции хранится на Transaction Inventory Page (TIP). Единственным измененим БД при подтверждении транзакции является смена состояния этой транзакции с Активной на Подтвержденную. Когда транзакция вызывает процедуру отмены, она проверяет свой Update Flag – если он не установлен, то значит никаких изменений БД не было произведено, и нужно сделать Подтверждение (COMMIT) вместо Отмены (ROLLBACK). Таким образом, отмена read-only транзакций не нагружает БД.Каким образом транзакция переходит из Активного состояния в Отмененное если завершение происходит по сбою?
Это может произойти двумя путями.
- Когда транзакция стартует, она делает блокировку собственного идентификатора транзакции. Если транзакция B пытается изменить или удалить запись, и обнаруживает что версия записи была создана транзакцией A, состояние в TIP которой Активное, транзакция B пытается вызвать конфликт блокировки идентификатора транзакции A. Если блокировка прошла, то транзакция B решает что A умерла, и меняет состояние A в TIP с Активного на Отмененное.
- Когда транзакция стартует, она проверяет, можно ли установить полную блокировку на БД. Вообще транзакции при работе устанавливают разделяемые блокировки на БД. Следовательно, если транзакции удается поставить полную блокировку, то других транзакций нет, и она конвертирует все Активные состояни в TIP на Отмененные.
Мусор
Borland InterBase – СУБД с многоверсионностью данных. Когда запись изменяется, на страницу данных помещается ее копия с новыми значениями, однако старая запись остается. Старое значение называется «Back Version» (резервная версия), и является «историей отката» – если транзакця, изменившая запись, отменится, то старая версия записи тут как тут, на своем старом месте. Кроме этого, старые версии обеспечивают уровень изоляции Repeatable Read (воспроизводимое чтение) для длинных транзакций, которым на все время действия нужно видеть данные, существовавшие на момент начала такой транзакции.Когда изменяющая записи транзакция подтверждается, и все конкурирующие тразнакции также завершаются, старая версия перестает быть необходимой. В часто изменяемой базе данных старые записи могут занимать значительное дисковое пространство и ухудшать производительность БД. Поскольку такие записи являются МУСОРОМ, его необходимо вычищать.
Сборка мусора
Сборка мусора предотвращает наполнение интенсивно обновляемой БД ненужными старыми версиями записей. Также уничтожаются версии записей, созданные отмененными транзакциями (Rolled Back). Каждая транзакция участвует в сборке мусора, в том числе и только читающие (read-only) транзакции.Когда транзакция считывает запись, на самом верхнем уровне она получает эту запись (это относится к любой записи в БД). Двумя уровнями ниже, где-то в недрах сервера, Borland InterBase вытаскивает с диска набор версий. (Прим. пер.: поскольку версии записей хранятся на страницах данных, а механизм работы со страницами оптимизирован для работы с версиями, лишних операций кроме чтения страниц данных не происходит). Каждая версия имеет идентификатор создавшей ее транзакции. Первой в списке версий идет самая старая запись. В этот момент сервер имеет две задачи:
- выдать правильную версию записи запросившей ее транзакции
- удалить все версии, являющиеся мусором – т. е. те версии, которые были созданы отмененными транзакциями или слишком старые версии записей, чтобы в них кто-то был заинтересован.
Существует и третий случай сборки мусора, который происходит в этот же момент. Кроме многоверсионных обновлений сервер использует и многоверсионные удаления. Когда транзакция удаляет запись, должна ли такая запись быть сразу удалена? Конечно нет! Удаление ведь может быть отменено. Поэтому вместо удаления записи, сервер выставляет метку удаления для старой версии записи. Если рано или поздно транзакция завершится, то вся запись вместе с меткой удаления и со своими предыдущими версиями станет мусором, и… (вы угадали!) когда-нибудь будет физически удалена.
Сборка мусора – итог
Сборка мусора является кооперативной. Это означает что все транзакции участвуют в ней (а не какая-то специально выделенная команда мусорщиков). Старые версии, удаленные записи, и отмененные изменения (и добавления) уничтожаются, когда транзакция пытается прочитать запись. (Прим. пер.: именно этим объясняются «странные» задержки в отработке запросов, например если вы выдали SELECT на таблице, из которой другой человек прямо перед вами удалил тысяч сто (100000) записей – вашей транзакции выпало «счастье» убирать мусор за предыдущей транзакцией).Периодическое архивирование БД (backup) также производит сборку мусора, поскольку считывает абсолютно все записи из БД. (Прим. пер.: если в момент backup есть активные транзакции, то некоторый мусор после их завершени безусловно останется. если не хотите, чтобы backup собирал мусор, указывайте ключ -g в командной строке gbak).
Старейшая заинтересованная транзакция (OLDEST INTERESTING TRANSACTION)
Для того чтобы определить, какие версии записей могут быть удалены при сборке мусора, и какие изменения отменены и могут быть игнорированы, каждая транзакция имеет «маску» «заинтересованых» транзакций». Транзакция является «заинтересованной» по отношению к другой транзакции, если она конкурирует с ней – т. е. ее изменения не подтверждены, или она отменена (ее изменения должны игнорироваться или такая транзакция в состоянии limbo).«Маска транзакций» – это снимок состояний всех транзакций от старейшей заинтересованной (OIT) до текущей. Размер снимка зависит от количества транзакций, стартовавших с момента старта старейшей заинтересованной транзакции. (Прим. пер.: собственно, здесь речь идет про TIP).
Старейшая активная транзакция (OLDEST ACTIVE TRANSACTION)
Примечание KDV. То, что Ann здесь именует как Oldest Active Transaction, на самом деле всегда было и есть Oldest Snapshot Transaction. См. www.ibase.ru/summary/, www.ibase.ru/ibtrans/. Звучит просто, но на самом деле не очень. Старейшая активная транзакция это не старейшая, живущая до настоящего момента. И не старайшая транзакция помеченная как Активная в TIP. Это старейшая транзакция, которая была активной, когда началась старейшая активная в текущий момент транзакция. Читать такие выражения довольно трудно, и я не помню как это было сделано, но это так, и это работает.(Прим. пер.: следующий абзац переводите сами)
Any record version behind a committed version created by a transaction older than the oldest transaction active when the oldest transaction currently active started is garbage and will never be needed ever again. That’s pretty dense. Lets ignore the commit/rollback question briefly.
Простой случай: Я транзакция 20. Я нахожу запись созданную и подтвержденную транзакцией 15. Я изменяю ее и подтверждаю изменения. Вы – транзакция 25, и когда вы стартуете, вы являетесь единственной активной транзакцией. Вы читаете запись, и обнаруживаете что все активные транзакции (стартовавшие после вас) могут использовать версию записи, созданную мной, поэтому вы собираете мусор – оригинальную версию этой записи. В этом случае, право на сборку мусора (как старейшей активной транзакции) ваше.
Тяжелый случай: Вы продолжаете работу, изменяя данные тут и там. Другая транзакция, например 27, стартует. Вы являетесь старейшей заинтересованной. Та, 27-а транзакция, тоже может изменять данные тут и там, кроме тех записей, что вы модифицировали. 27-ая завершается и подтверждает изменения. Я стартую транзакцию 30. Вы также являетесь для меня старейшей заинтересованной транзакцией, и я не могу собирать мусор поскольку новые версии записей моложе вас. Я нахожу запись, созданную транзакцией 15, измененную транзакцией 20, и затем опять измененную транзакцией 27. Все три этих транзакции завершены и подтверждены, но я могу собрать мусор только в виде оригинальной версии записи, созданной транзакцией 15. Т. к. версия, созданная транзакцией 27, для меня стара, но не стара для вас, я решаю, что вы можете быть заинтересованы в этой версии записи.
Тяжелейший случай: Я транзакция 87, и когда я стартую, все транзакции до 75-ой завершились подтверждением, и все после 75-ой в настоящее время активны. Транзакция 77 модифицирует запись, созданную транзакцией 56. Я продолжаю читать версию 56-ой транзакции. Все нормально. Транзакция 77 завершается подтверждением. Вы – транзакция 95. Когда вы стартуете, я (87-ая) являюсь старейшей активной. Вы читаете запись созданную 56-ой и модифицированную 77-ой. Вы не можете собирать мусор для этой записи, поскольку я не могу читать записи созданные транзакцией после 74-ой (они еще не все завершены).
Надеюсь что вы теперь поняли, что понятие «старейшей активной» транзакции не так просто, как кажется.
Чистка (SWEEPING)
Чистка – это НЕ только сборка мусора. Основная работа, которую делает чистка, это перемещение старейшей заинтересованной транзакции «вверх», и уменьшение размера маски транзакций. Это делается переводом Отмененных транзакцией в Подтвержденные транзакции.Вы скажете – «Она сошла с ума!»
Но это, действительно, основная работа чистки. Она удаляет все изменения, сделанные отмененными транзакциями, затем меняет их состояние на Подтвержденное. (Помните, было сказано, что отмененные read-only транзакции получают состояние подтвержденных. Удалите изменения, и можно считать что транзакция завершилась подтверждением).
В то же время, чистка собирает мусор так же, как и любая другая транзакция.
До версии 4.2, несчастливая транзакция, включившая чистку, сама выполняла ее, и только затем отрабатывалась. Другие транзакции продолжали работать. В версии 4.2 и выше, запускается новый поток и самостоятельно производит чистку, в то время как все остальные транзакции нормально работают.
Транзакции «in limbo»
Транзакции in limbo не могут быть переведены в другое состояние автоматически, будут приводить к постоянному включению чистки, и будут блокировать попытки изменения или удаления созданных ими версий. В любом случае Borland InterBase предоставляет хорошую диагностику при возникновении сбоев при two phase commit (утилита Server Manager).Несколько примеров
Все это я написала после несчастного случая с процессом, который вставлял миллион записей с отдельной подтвержденной транзакцией на каждую запись. Процесс быстро довел себя до скорости улитки, и вину в этом возложили на чистку. Ну, может быть, проблема была и в чистке, и все же я сомневаюсь!Случай 1. Поток неконкурирующих транзакций
Транзакция 1 вставляет запись 1 и завершается подтверждением. Транзакция 2 стартует и становится одновременно старейшей активной и старейшей заинтересованной. Она вставляет запись 2 и завершается подтверждением. Транзакция 3 стартует, также становится старейшей активной и заинтересованной, вставляет свою запись и завершается подтверждением. В конце концов транзакция 1000000 стартует, опять становится старейшей активной и заинтересованной. Чистки не происходит (в общем-то чистить и нечего).
Случай 2. Готовится засада
Транзакция 1 стартует, оглядывается, и идет покурить. Транзакция 2 стартует, обнаруживает что 1-ая является старейшей активной и
заинтересованной, вставляет запись 1 и завершается подтверждением. Транзакция 3 стартует, обнаруживает что 1-ая все еще старейшая активна и заинтересованная, вставляет запись 2 и завершается подтверждением. В конце концов транзакция 1000001 стартует, видит что 1-ая все еще старейша активная и заинтересованная, т. е. разница между OAT и OIT равна 0, и завершается. Опять чистка не возникает.
Случай 3. Кто попадет в засаду?
Транзакция 1 стартует, что-то делает и идет покурить. Транзакция 2 стартует, обнаруживает что 1-ая является старейшей активной и заинтересованной, вставляет запись 1 и завершается. Транзакция 3 стартует, обнаруживает что 1-ая является старейшей активной и заинтересованной, вставляет запись 2 и завершается. Вдруг транзакция 1 отравляется никотином и умирает прямо в курительной комнате (допустим, не так страшно, а просто происходит обрыв связи между клиентским компьютером и сервером). Транзакция 15034 стартует (к счастью), получает возможность установить монопольную блокировку на файл базы данных, и устанавливает состояние транзакции 1 в Отмененное. Теперь старейшая заинтересованная имеет номер 1, но старейшая активная уже имеет номер 15034. Разница составляет 15033, поэтому уборка (sweep) не начинается. Через 4967 транзакций происходит уборка. После того как она закончена, идентификаторы старейшей заинтересованной и активной становятся равными, и следущий процесс уборки может начаться только если возникнет заинтересованная транзакция, перешедшая в неактивное состояние.
Случай 4. Смертельные качели
Предположим, что в нашей системе происходят парные транзакции, одна из которых завершается подтверждением, а другая откатом. Проблема в том, что транзакция, завершенная откатом, становится старейшей заинтересованной (OIT), а транзакция завершенная подтверждением – соответственно старейшей активной (OAT). Если после транзакции, завершившейся откатом, произойдет еще одна откатываемая транзакция, то она не станет OIT, поскольку предыдуща является «старейшей». Таким образом после даже единственной завершенной откатом транзакции, каждая последующая подтверждаемая транзакция будет увеличивать разницу между OIT и OAT. И через 20001 завершенных подтверждением транзакций действительно произойдет ЧИСТКА (SWEEP).Итог
Итак, мы с вами выяснили к чему может привести вставка 1000000 записей с транзакцией на каждую запись. Может быть стоит выключить forced write (параметр БД в Server Manager)? Или настала пора запустить дефрагментацию диска?свойства ACID, управление с помощью команд и работа с изменениями в базе данных
От автора: транзакция — это единица работы, которая выполняется в отношении базы данных. Транзакции SQL — это единицы работы или последовательности действий, выполненных в логическом порядке: вручную или автоматически с помощью какой-либо программы базы данных.
Транзакция — это осуществление одного или нескольких изменений базы данных. Например, если вы создаете, обновляете или удаляете запись из таблицы, вы выполняете в этой таблице транзакцию. Важно контролировать транзакции, чтобы обеспечить целостность данных и обрабатывать ошибки базы данных.
Практически вы собираете множество SQL-запросов в группу, и они будут выполняться вместе как часть транзакции.
Свойства транзакций
Транзакции имеют следующие четыре стандартных свойства, обычно обозначаемых аббревиатурой ACID.
Атомарность – обеспечивает, чтобы все операции входящие в единицу работы были завершены успешно. В противном случае транзакция прерывается в момент сбоя, и все предыдущие операции возвращаются в прежнее состояние.
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
Получить курс сейчас!Согласованность — обеспечивает, чтобы база данных надлежащим образом изменяла состояние при успешной транзакции.
Изолированность — позволяет транзакциям работать независимо друг от друга и прозрачно.
Долговечность — гарантирует, что результат совершенной транзакции сохранится в случае сбоя системы.
Управление транзакциями
Для управления транзакциями используются следующие команды.
COMMIT — сохранить изменения.
ROLLBACK — отменить изменения.
SAVEPOINT — создает точки сохранения в группах транзакций.
SET TRANSACTION — помещает имя в транзакцию.
Команды управления транзакциями
Команды управления транзакциями используются только с командами DML, такими как — INSERT, UPDATE и DELETE. Они не могут использоваться при создании таблиц или их удалении, поскольку эти операции автоматически фиксируются в базе данных.
Команда COMMIT
Команда COMMIT — это транзакционная команда, используемая для сохранения изменений внесенных транзакцией в базу данных. Команда COMMIT сохраняет все транзакции в базе данных с момента выполнения последней команды COMMIT или ROLLBACK.
Синтаксис команды COMMIT следующий.
Пример
Рассмотрим таблицу CUSTOMERS, содержащую следующие записи:
Ниже приведен пример, в котором из таблицы будут удалены клиенты с возрастом = 25, а затем эти изменения будут сохранены в базе данных.
DELETE FROM CUSTOMERS WHERE AGE = 25; COMMIT;
DELETE FROM CUSTOMERS WHERE AGE = 25; COMMIT; |
Таким образом, из таблицы будут удалены две строки, и результат выполнения инструкции SELECT будет выглядеть следующим образом.
Команда ROLLBACK
Команда ROLLBACK — это транзакционная команда, используемая для отмены транзакций, которые еще не были сохранены в базе данных. Эта команда может использоваться только для отмены транзакций с момента выполнения последней команды COMMIT или ROLLBACK.
Синтаксис команды ROLLBACK следующий:
Пример
Рассмотрим таблицу CUSTOMERS, содержащую следующие записи:
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
Получить курс сейчас!Ниже приведен пример, в котором из базы данных будут удалены все записи для которых возраст = 25, а затем эти изменения будут отменены.
DELETE FROM CUSTOMERS WHERE AGE = 25; ROLLBACK;
DELETE FROM CUSTOMERS WHERE AGE = 25; ROLLBACK; |
Таким образом, операция удаления не приведет к изменениям в таблице, и результат выполнения инструкции SELECT будет выглядеть следующим образом.
Команда SAVEPOINT
SAVEPOINT – это точка транзакции, к которой вы можете вернуть транзакцию, не откатывая ее полностью. Синтаксис команды SAVEPOINT приведен ниже.
SAVEPOINT SAVEPOINT_NAME;
SAVEPOINT SAVEPOINT_NAME; |
Эта команда предназначена только для создания SAVEPOINT в других транзакционных операторах. Команда ROLLBACK используется для отмены группы транзакций до точки SAVEPOINT.
Синтаксис, который используется для возврата к SAVEPOINT, показан ниже.
ROLLBACK TO SAVEPOINT_NAME;
ROLLBACK TO SAVEPOINT_NAME; |
Ниже приведен пример ситуации, когда мы планируем удалить три разных записи из таблицы CUSTOMERS. Мы можем создать SAVEPOINT перед каждым удалением, чтобы иметь возможность откатить операцию к любой SAVEPOINT любое время и вернуть данные в исходное состояние.
Пример
Рассмотрим таблицу CUSTOMERS, содержащую следующие записи.
Следующий блок кода содержит ряд операций.
SAVEPOINT SP1; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=1; 1 row deleted. SAVEPOINT SP2; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=2; 1 row deleted. SAVEPOINT SP3; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=3; 1 row deleted.
SAVEPOINT SP1; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=1; 1 row deleted. SAVEPOINT SP2; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=2; 1 row deleted. SAVEPOINT SP3; Savepoint created. DELETE FROM CUSTOMERS WHERE ID=3; 1 row deleted. |
Теперь, после того как были выполнены изменения, предположим, что вы передумали и решили откатить операцию к точке SAVEPOINT, которую вы определили как SP2. Поскольку SP2 была создана после первого удаления, последние два удаления будут отменены:
ROLLBACK TO SP2; Rollback complete.
ROLLBACK TO SP2; Rollback complete. |
Обратите внимание, что перед тем как мы вернулись к SP2, было произведено первое удаление
Команда RELEASE SAVEPOINT
Команда RELEASE SAVEPOINT используется для удаления созданной точки SAVEPOINT. Синтаксис команды RELEASE SAVEPOINT следующий.
RELEASE SAVEPOINT SAVEPOINT_NAME;
RELEASE SAVEPOINT SAVEPOINT_NAME; |
После того как SAVEPOINT будет удалена, вы больше не сможете использовать команду ROLLBACK для отмены транзакций, выполненных после последней SAVEPOINT.
Команда SET TRANSACTION
Команда SET TRANSACTION может использоваться для инициирования транзакции базы данных. Эта команда используется для указания характеристик транзакций, которая задается после команды. Например, вы можете задать для транзакции режим только чтения или чтение и запись. Синтаксис команды SET TRANSACTION следующий.
SET TRANSACTION [ READ WRITE | READ ONLY ];
SET TRANSACTION [ READ WRITE | READ ONLY ]; |
Источник: //www.tutorialspoint.com/
Редакция: Команда webformyself.
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
Получить курс сейчас!Хотите изучить MySQL?
Посмотрите курс по базе данных MySQL!
СмотретьТранзакции в SQL на примере базы данных SQLite: свойства ACID и уровни изоляции транзакций в SQLite3
Привет, посетитель сайта ZametkiNaPolyah.ru! Продолжаем изучать базы данных и наше знакомство с библиотекой SQLite3. Сегодня мы поговорим про транзакции в реляционных базах данных и языке запросов SQL. Транзакция — одна из самых сложных функций СУБД и языка SQL с точки зрения реализации самой СУБД. Транзакции не только обеспечивают целостность данных в базах данных, но и реализуют функции, позволяющие работать нам с файловой системой компьютера при помощи СУБД. Вообще реализация механизмов транзакции зависит от СУБД, в этой записи мы познакомимся в общих чертах с тем, как реализованых транзакции в базах данных под управлением SQLite.
Транзакции в SQL на примере базы данных SQLite: свойства ACID и уровни изоляции транзакций в SQLite3.
Но начнем мы эту запись с того, что дадим ответ на вопрос: «что такое транзакция в SQL?» . Затем мы поговорим о свойствах транзакций в реляционных базах данных, сразу скажем, что свойства транзакций одновременно являются еще и требованиями, их всего четыре и называется это всё дело ACID. Также мы рассмотрим проблемы, которые могут возникать при выполнении нескольких транзакций параллельно и как с этими проблемами бороться при помощи блокировки таблиц и изоляции транзакций. В завершении данной записи мы рассмотрим SQL синтаксис транзакций, реализованный в библиотеки SQLite3 и увидим, что SQLite позволяет давать имена транзакциям и создавать вложенные транзакции.
Что такое транзакция в контексте базы данных и языка SQL?
Содержание статьи:
Давайте разберемся с тем, что такое транзакция в контексте языка SQL и в реляционных базах данных с технической точки зрения. Многие утверждают, что транзакция в базе данных – это есть объекта базы данных, как, например, VIEW или триггер. Другие говорят: нет, транзакция в SQL – это процесс. На мой взгляд правы и те, и другие.
Если смотреть на транзакцию «глазами СУБД», то это объект базы данных, который живет ровно столько, сколько длится тот или иной процесс. Давайте дадим определение термину транзакция. Транзакция – это неделимый процесс, который включает в себя группу последовательных операций (этих операций может быть очень много) над данными в базе данных. Операции в транзакции могут быть либо выполнены целиком и полностью все, либо не выполнены вообще.
При этом соблюдается целостность данных в базе данных, а транзакция выполняется вне зависимости и параллельно от других транзакций. В качестве жизненного примера транзакций в базе данных можно описать следующую ситуацию. Например, вы оплачиваете покупку в магазине, это неделимое действие, которое условно можно разбить на несколько операций:
- Кассир пробивает товар.
- Вы даете ему карточку.
- Кассир вставляет карточку в картоприемник.
- Вы вводите пин-код.
- Происходит перечисление денег с вашего счета на счет магазина.
- Кассир отдает вам карточку с чеком.
- Вы забираете товар и уходите.
Довольно простое и незамысловатое действие, которое мы совершаем каждый день. И согласитесь, у этого действия может быть два окончания: либо вы оплатили товар и забрали его, либо вы его не оплатили, и вам его не отдали. Забрать пол телевизора или половину бутылки с газировкой вы не сможете. Это типичный пример транзакций в SQL. Но, как и в любом процессе, в процессе оплаты товара могут возникать различные ошибки. Например, вы ввели пин-код и выключился свет, ничего страшного не произойдет: даже если запрос на перечисление ушел, деньги с вас не спишут, так как транзакция не была завершена успешно и, следовательно, произойдет откат всех операций, соответственно, вы останетесь при деньгах, но товар забрать не сможете.
А теперь представьте, что операция по переводу денег с одного счета на другой делалась бы не единой и неделимой транзакцией, а отдельными операциями: сколько бы тогда возникало ошибок, нарушений целостности данных и конфликтов. Но это не так страшно, куда важнее испорченные нервы покупателя и лиц его обслуживающих.
Итак, транзакция в базе данных – это неделимый процесс, состоящий из нескольких операций, которые могут быть выполнены все вместе целиком и успешно, либо произойдет откат этих операций. Транзакции повышают надежность и быстродействие операций в базе данных. С надежностью всё понятно, но за счет чего происходит увеличение быстродействия.
Мы знаем, что СУБД создает нам абстракцию. На самом деле все данные в базе данных – это обычный файл, лежащий на жестком диске, а СУБД представляет нам этот файл в виде базы данных, таблиц и других не естественных для файловой системы компьютера объектов. Поэтому, когда мы выполняем ту или иную операцию в базе данных, то СУБД, можно сказать, создает соединение с файлом на жестком диске, делает какие-то свои внутренние операции, затем выполняет SQL запрос и закрывает соединение с файлом. И, например, в SQLite каждый запрос к базе данных – это маленькая транзакция, состоящая из одной операции (за исключением команды SELECT).
Но, когда мы явно говорим SQLite о том, что хотим запустить транзакцию, она устанавливает соединение с файлом и не закрывает его до тех пор, пока транзакция не будет выполнена. Таким образом мы можем существенно экономить ресурсы, особенно, когда выполняем очень много однотипных операций, например, когда вставляем несколько сотен/тысяч строк в таблицу базы данных.
Если такую операцию мы будем выполнять без транзакции, то при каждом выполнении команды INSERT, SQLite будет открывать соединение и закрывать его, и эти две операции будут происходить столько раз, сколько вы строк будете вставлять. Если же мы сначала создадим транзакцию, то библиотека SQLite создаст только одно соединение и завершит его, когда транзакция будет завершена.
Четыре свойства транзакции в реляционных базах данных: ACID
У транзакций в реляционных базах данных есть четыре свойства. Можно еще сказать, что это не четыре свойства, а четыре требования к транзакциям в базах данных. Этих четыре требования получили название ACID. Итак, ACID – это четыре свойства транзакции. Каждая буква аббревиатуры ACID – это первая буква того или иного требования: Atomicity, Consistency, Isolation, Durability. В русском языке свойства транзакции имеют аналогичную аббревиатуру: АСИД, это можно расшифровать как: атомарность, согласованность, изолированность и долговечность.
Давайте перечислим четыре свойства транзакции ACID и посмотрим, какие требования предъявляются к транзакциям в базах данных:
- Atomicity или свойство атомарности транзакции гарантирует, то что ни одна транзакция в базе данных не будет выполнена частично. Вы не сможете честным путем забрать товар из магазина, отдав треть стоимости товара, а честный продавец не возьмет с вас денег за испорченный или разбитый товар. Поэтому внутри транзакции выполняются, либо все операции, и она успешно завершается, либо, если происходит сбой на одной из операций, происходит откат всех ранее выполненных операций. Таким образом обеспечивается целостность данных и поддерживается их согласованность.
- Consistency или требование согласованности базы данных до и после выполнения транзакции. Перед тем, как начинается транзакция, база данных находится в согласованном состояние (в спокойном состояние, чуть ниже это объясню на примере). Когда транзакция завершается, база данных должна находиться так же в согласованном состоянии. Например, вы оплатили покупку, вам пришло уведомление, что списали деньги, но продавец не видит поступивших на счет денег, и не отдает вам товар. Естественно, вы выйдете в этом случае из своего согласованного состояния и будете не очень спокойным (база данных в этом случае будет находиться так же в не согласованном состоянии: деньги с одного счета были списаны, а на другой не зачислены). Обратите внимание: что в процессе выполнения транзакции (когда выполняются операции) база данных может находиться в несогласованном состоянии, но как только транзакция завершена данное состояние недопустимо.
- Isolation или свойство изолированности транзакций. Это одно из самых дорогих требований к транзакциям в базе данных. Оно гарантирует то, что параллельно выполняемые транзакции не будут мешать друг другу. Из-за того, что свойство изолированности транзакций забирает большое количество ресурсов, в реальных СУБД созданы различные уровни изоляции транзакций, чем выше этот уровень, тем более изолированы транзакции.
- Durability или свойство долговечности транзакции. Перевод durability, как долговечность, в данном случае не совсем точно характеризует требование к транзакции, более точным будет свойство устойчивости транзакции. Требование устойчивости транзакции или долговечности гарантирует то, что база данных останется в согласованном состоянии вне зависимости от проблем на других уровнях модели OSI. Например, вы оплачиваете покупку, а в этот момент в здании выключается свет или происходит обрыв линии связи. База данных должна остаться согласованной в этом случае, то есть деньги должны остаться на вашем счету, но покупку вы забрать не сможете. Если же транзакция была выполнена успешно до возникновения технических проблем, то все устройства, работающие с базой данных, получат данные в согласованном состоянии, как только проблема будет устранена.
Обращу ваше внимание на то, что в каждой реализации СУБД свойства ACID реализуются по-разному. Но результат работы свойств ACID всегда один: база данных всегда находится в согласованном состоянии до и после выполнения транзакции. Если требования ACID выполняются, то транзакции могут работать параллельно, не мешая друг другу. Благодаря требованиям ACID транзакции не выполняются частично и, наконец, если транзакция подтверждена, то она подтверждена и никакие технические сбои этому не помешают.
Проблемы при выполнении параллельных транзакций
Ранее мы упоминали о том, что транзакции должны быть изолированы, а также мы сказали, что полная изоляция транзакции – очень дорогая операция, поэтому было принято разделение по степени изолированности. Чем выше уровень изолированности транзакции, тем выше точность и согласованность данных, но минус в том, что может уменьшится число параллельных транзакций, которые выполняются СУБД.
Также при выполнении параллельных транзакций в базе данных могут возникать некоторые проблемы. Ниже вы найдете список проблем, которые могут возникнуть при параллельных транзакциях:
- Потерянное обновление (lost update). Если две или более, запущенных параллельно транзакции пытаются модифицировать одни и те же данные, то все вносимые изменения, кроме первой транзакции, будут потеряны.
- Неповторяющееся чтение (non-repeatable read). При повторном чтении в рамках одной транзакции ранее прочитанные данные оказываются изменёнными.
- Грязное чтение (dirty read). Данная проблема возникает в том случае, когда вы делаете выборку данных, которые были изменены транзакцией, но в дальнейшем произойдет откат транзакции и эти изменения не подтвердятся.
- Фантомное чтение (phantom reads). Представим, что у нас запущено две транзакции, первая лишь читает данные из базы данных, вторая манипулирует данными, например: добавляет строки, удаляет данные или их модифицирует. Допустим, что в первой транзакции условия выборки данных всегда одинаковые, но результаты могут оказаться разными, так как вторая транзакция изменяет данные в таблицах.
Справиться с подобными проблемами при выполнении параллельных транзакций помогают блокировки и изолированность транзакций.
Изолированность транзакций в базе данных. Блокировка SQL таблиц в базах данных
В информатике есть такое понятие как уровни изолированности транзакций, которые помогаю справляться с вышеперечисленными проблемами. Стандарт SQL-92 выделяет четыре уровня изолированности транзакций в реляционных базах данных. Чем выше уровень изолированности, тем меньше проблем может возникнут, а это значит, тем лучше происходит обеспечение целостности данных.
Заметим, что каждый последующий уровень изолированности включает требования предыдущего уровня и добавляет некоторые свои требования (нечто похожее мы наблюдали, когда говорили про нормальные формы в базе данных: третья нормальная форма включает в себя требования второй нормальной формы и первой нормальной формы, плюс накладывает свои требования на отношение).
- Read uncommitted (чтение незафиксированных данных). Уровень изолированности Read uncommitted или чтение незафиксированных данных – это самый низший уровень изолированности транзакций. Данный уровень справляется с проблемами потерянного обновления. Обычно этот уровень реализуется путем блокировки таблиц для других транзакций. Например, выполняется первая транзакция и, пока она выполняется, ни одна другая транзакция не может изменять данные в этой таблице, а может их только читать. При этом, как только завершится первая транзакция, таблица станет доступна для второй транзакции, которая может изменять данные. Таким образом при уровне изоляции Read uncommitted транзакции будут выполняться последовательно и ни одно изменение потеряно не будет. Но в то же самое время любая другая транзакция может выполнять чтение данных из этой таблицы (даже тех данных, которые еще не были подтверждены командой COMMIT).
- Read committed (чтение фиксированных данных). Данный уровень изолированности транзакций решает проблему грязного чтения данных. Но уровень изолированности Read committed или чтение фиксированных данных может быть реализован двумя способами.
- Первый способ заключается в том, что читающая транзакция блокирует считываемые данные и при этом транзакция, выполняющая какие-то изменения не может их совершить до тех пор, пока читающая транзакция не будет завершена. Если же пишущая транзакция началась раньше, то она блокирует данные для читающих транзакций до тех пор, пока изменения не будут подтверждены. Этот способ получил название блокирование или блокирование читаемых и изменяемых данных.
- Второй подход или второй способ изоляции основан на версионности данных. СУБД создает новую версию строки для транзакции при каждом изменении данных строки. С этой новой версией продолжает работать та транзакция, которая ее создала, но любая другая транзакция видит строку в том, виде, в котором она была зафиксирована. Этот способ гораздо быстрее первого, но требует гораздо большего объема оперативной памяти, так как «новые версии строк» хранятся в оперативной памяти до тех пор, пока они не будут подтверждены.
- Repeatable read (повторяемость чтения). Уровень изоляции транзакции Repeatable read или повторяемость чтения делает так, что транзакция, изменившая данные, не видит своих изменений, до тех пор, пока они не будут подтверждены. При этом никакая другая транзакция не сможет вносить изменения, пока не будет завершена первая транзакция.
- Serializable (упорядочиваемость). Уровень изоляции транзакции Serializable или упорядочиваемость – самый высокий уровень изолированности транзакций, описанный в стандарте SQL-92. На этом уровне транзакции не подвержены проблемам фантомного чтения, так как уровень Serializable (упорядочиваемость) делает их, можно сказать, последовательными. На данном уровне транзакции максимально изолированы друг от друга.
Обратите внимание: четыре уровня изолированности транзакций описаны в стандарте SQL-92, каждая СУБД поддерживает разное количество уровней изолированности транзакций (какие-то имеют большее количество уровней, какие-то меньшее), а также в каждой СУБД реализован свой подход к изоляции транзакций. Ниже мы несколько более подробно поговорим о том, как реализованы транзакции в базах данных под управлением библиотеки SQLite.
Синтаксис транзакций в базах данных под управлением SQLite
Мы уже подробно разбирали синтаксис транзакций в базах данных под управлением SQLite3, давайте немного повторим сказанное ранее. Отмети также, что любая SQL команда, за исключением SQL запросов SELECT, будет автоматически начинать транзакцию и завершать ее после выполнения операции.
Начать транзакцию в SQLite
Начать транзакцию в базе данных под управлением SQLite позволяет команда BEGIN TRANSACTION (ключевое слово TRANSACTION необязательное и его можно не присать). Ниже вы можете увидеть общий синтаксис команды BEGIN TRANSACTION.
Начать транзакцию в SQLite
Транзакции в SQLite3 имеют три режима блокировки: DEFERRED, IMMEDIATE, EXCLUSIVE. Также стоит заметить, выполнение свойств ACID в SQLite достигается не только путем блокировок, но еще и при помощи журнализации изменений. Давайте посмотрим, как происходит блокировка данных в этих трех режимах:
- DEFERRED – данный режим блокировки является режимом по умолчанию в SQLite. В режиме DEFERRED SQLite начинает блокировать таблицы только после того, как будет начато выполнение какой-либо команды, при этом другие транзакции могут читать данные из таблицы, но не могут их изменять.
- IMMEDIATE – в данном режим происходит блокировка базы данных, как только будет выполнена команда BEGIN. При это режим IMMEDIATE в SQLIte допускает, что другие транзакции могут читать данные из базы данных, но не записывать.
- EXCLUSIVE – самый высокий уровень блокировки базы данных в SQLite. Режим EXCLUSIVE блокирует базу данных при выполнении команды BEGIN и при этом другие транзакции не могут ни читать данные из базы данных, ни уж тем более изменять данные.
Как видим, SQLite ориентирована на обеспечение целостности данных и согласованность данных при выполнении транзакций. Мне кажется, что данный подход обусловлен тем, что SQLite в первую очередь используется на мобильных устройствах, которые не имеют постоянных источников питания.
Подтвердить транзакцию в SQLite3
Подтвердить изменения, внесенные транзакцией, позволяет ключевая фраза COMMIT TRANSACTION. Синтаксис подтверждения изменений, вносимых транзакцией, вы можете увидеть на рисунке ниже.
Подтвердить транзакцию в SQLite3
Заметим, что у команды COMMIT есть псевдоним END, а ключевое слово TRANSACTION является необязательным и его можно не писать.
Откатить транзакцию в SQLite
Откатить транзакции в базах данных под управлением SQLite позволяет ключевое слово ROLLBACK. Синтаксис команды ROLLBACK в SQLite3 показан на рисунке ниже.
Откатить транзакцию в SQLite
Транзакции в SQLite могут быть вложенными (nested), поэтому откатывать можно не только к началу, но и к контрольной точки (ROLLBACK TO SAVEPOINT), отметим, что ключевое слово TRANSACTION также не является обязательным при выполнении команды ROLLBACK.
Альтернативный синтаксис транзакций в SQLite3: транзакции с именем, вложенные транзакции и контрольные точки
В SQLite есть альтернативный синтаксис транзакций, реализуемый при помощи команды SAVEPOINT, но это не только альтернативный синтаксис транзакций в SQLite, который вы сможете увидеть ниже, но еще и возможность сделать вложенную транзакцию.
Начать вложенную транзакцию с именем
Закрыть вложенную транзакцию
Обратите внимание на некоторые моменты создания транзакций в SQLite при помощи ключевого слова SAVEPOINT:
- Ключевое слово SAVEPOINT позволяет создавать вложенные транзакции.
- Если мы инициируем транзакцию ключевым словом SAVEPOINT, то у транзакции обязательно должно быть имя, которое может быть неуникальным.
- Для успешного подтверждения изменений транзакций, начатых командой SAVEPOINT используется ключевое слово RELEASE. Но, если команда RELEASE применяет к вложенной транзакции, то она просто удаляет контрольную точку, только команда RELEASE, которая будет применена к внешнему SAVEPOINT, будет работать, как COMMIT.
- Ключевое слово ROLLBACK TO откатывает все изменения, внесенные после создания контрольной точки и возвращает базу данных в то состояния, в котором она была на момент создания контрольной точки.
Таким образом в базах данных SQLite мы можем создавать транзакции с именем, которые одновременно являются вложенными транзакциями и контрольными точками.
9 Транзакции и блокировки — СтудИзба
1. Транзакции и блокировки
2. Понятие транзакции
При работе с базами данных не исключены ошибки и сбои. Они могут быть вызваны ошибками пользователей, взаимодействующих с СУБД, или неустойчивой работой компьютеров. Поэтому в СУБД применяют специальные способы отмены действий, вызвавших такие ошибки. Команда SQL, оказывающая действие на содержание и структуру БД, не является необратимой. Пользователь может установить, что произойдет после окончания ее действий: останутся ли внесенные изменения БД или они будут проигнорированы. Для этого последовательность операций над базой данных объединяют в группы — транзакции.
Транзакцией называется последовательность операций, производимых над базой данных и переводящих ее из одного непротиворечивого состояния в другое непротиворечивое состояние.
Транзакция рассматривается как некоторое неделимое действие над БД, осмысленное с точки зрения пользователя, то есть это логическая единица работы системы. Транзакция начинается всякий раз, когда происходит сеанс работы с базой данных.
Примером транзакции может быть перевод денег через банкомат. Сумма 100 т.р. переводится с текущего счета на карт-счет. Программа вычитает сумму с текущего счета, после чего прибавляет ее к карт-счету. Во время работы программы после выполнения первой модификации происходит сбой питания, и увеличения карт-счета не происходит. Для того чтобы избежать подобной ситуации обе команды должны быть объединены в транзакцию. В случае, когда все команды транзакции не выполняются, происходит откат транзакции.
Определим транзакцию по вводу данных о вновь поступивших в библиотеку книгах. Эту операцию можно разбить на 2 последовательные: сначала ввод данных о книге – это новая строка в таблице Книги. Затем необходимо ввести данные обо всех экземплярах книги — это ввод набора новых строк в таблицу Экземпляры. Если эта последовательность действий будет прервана, то база данных не будет соответствовать реальному объекту, поэтому желательно выполнять ее как единую работу над базой данных.
3. Свойства транзакций. Способы завершения транзакций
Существуют различные модели транзакций, которые могут быть классифицированы на основе различных свойств, включающих структуру транзакции, параллельность внутри транзакции, продолжительность и т.д.
Рекомендуемые файлы
В настоящее время выделяют следующие типы транзакций: плоские или классические транзакции, цепочечные транзакции и вложенные транзакции.
Плоские транзакции характеризуются классическими свойствами: атомарности, согласованности, изолированности и долговечности.
· Свойство атомарности выражается в том, что транзакция должна быть выполнена в целом или не выполнена вовсе.
· Свойство согласованности гарантирует, что по мере выполнения транзакции данные переходят из одного согласованного состояния в другое согласованное состояние — транзакция не разрушает взаимной согласованности данных.
· Свойство изолированности означает, что конкурирующие за доступ к БД транзакции физически обрабатываются последовательно, изолированно друг от друга, но для пользователей это выглядит так, как будто они выполняются параллельно.
· Свойство долговечности означают, что если транзакция завершена успешно, то те изменения данных, которые были ею произведены, не могут быть потеряны ни при каких обстоятельствах, даже в случае последующих ошибок.
Возможны 2 варианта завершения транзакции:
· если все операторы выполнены успешно и в процессе транзакции не произошло никаких сбоев программного или аппаратного обеспечения, транзакция фиксируется. (Фиксация – это запись на диск изменений в БД, которые были сделаны в процессе выполнения транзакции). До тех пор, пока транзакция не зафиксирована, эти изменения могут быть аннулированы и база данных может быть возвращена в то состояние, в котором она была на момент начала транзакции. Фиксация транзакции означает, что все результаты выполнения транзакции становятся постоянными. Они станут видимы другим транзакциям только после того, как текущая транзакция будет зафиксирована.
· Если в процессе выполнения транзакции произошел сбой, БД должна быть возвращена в исходное состояние. Откат транзакции – это действие, обеспечивающее аннулирование всех изменений данных, которые были сделаны операторами SQL в теле текущей незавершенной транзакции.
4. Операторы Transact SQL для работы с транзакциями
В стандарте ANSI/ISO определены операторы СOMMIT и ROLLBACK, в стандарте начало транзакции неявно задается первым оператором модификации данных; Оператор COMMIT означает успешное завершение транзакции, результаты транзакции фиксируются во внешней памяти; при завершении транзакции оператором ROLLBACK результаты транзакции отменяются. Успешное завершение программы, в которой была инициирована транзакция, означает успешное завершение транзакции (как если бы был использован оператор COMMIT), неуспешное завершение – прерывает транзакцию (как будто был использован оператор ROLLBACK). В этой модели каждый оператор, изменяющий состояние данных, рассматривается как транзакция. Такая модель была реализована в первых версиях коммерческих СУБД. В дальнейшем в СУБД SYBASE была реализована расширенная модель транзакций.
В расширенной модели транзакций (например, в СУБД SQL SERVER) предусмотрен ряд дополнительных операций:
· оператор BEGIN TRANSACTION сообщает о начале транзакции;
· оператор COMMIT TRANSACTION сообщает об успешном завершении транзакции. Этот оператор, также как и COMMIT в модели стандарта ANSI/ISO, фиксирует все изменения, которые производились в БД в процессе выполнения транзакции;
· оператор SAVE TRANSACTION создает внутри транзакции точку сохранения, которая соответствует промежуточному состоянию БД, сохраненному на момент выполнения этого оператора. В операторе SAVE TRANSACTION может стоять имя точки сохранения, поэтому в ходе выполнения транзакции может быть запомнено несколько точек сохранения соответствующих нескольким промежуточным состояниям;
· оператор ROLLBACK имеет 2 модификации. Если он используется без дополнительного параметра, то он интерпретируется как оператор отката всей транзакции, если же он имеет параметр ROLLBACK n, то он интерпретируется как оператор частичного отката транзакции в точку сохранения n.
Точки сохранения целесообразно использовать в длинных и сложных транзакциях, чтобы обеспечить возможность отмены изменений, выполненных определенными операторами.
В большинстве случаев можно установить параметр, называемый AUTOCOMMIT, который будет автоматически запоминать все выполняемые команды, причем действия, которые привели к ошибке, всегда будут автоматически отменены. Обычно этот режим устанавливается с помощью команды типа:
SET AUTOCOMMIT ON;
а возврат к обычной диалоговой обработке запросов:
SET AUTOCOMMIT OFF;
Кроме того, имеется возможность установки AUTOCOMMIT, которую СУБД выполнит автоматически при регистрации, Если сеанс пользователя завершился аварийно, – например, произошел сбой системы, то текущая транзакция выполнит автоматический откат изменений. Не рекомендуется организовывать работу так, чтобы одиночные транзакции содержали много команд, тем более не связанных между собой. Это может привести к тому, что при отмене изменений будет выполнено слишком много действий, в том числе и тех, которые являются нужными и ошибки не вызвали. Лучший вариант, когда транзакция состоит из одной команды или нескольких тесно связанных команд.
Триггер выполняется как неявно определенная транзакция, поэтому внутри триггера допускается применение команд управления транзакциями. В частности, при обнаружении нарушения ограничений целостности для прерывания выполнения триггера и отмены всех изменений, которые пытался выполнить пользователь, необходимо использовать команду ROLLBACK TRANSACTION. В случае успешного завершения триггера можно использовать команду COMMIT TRANSACTION.
Выполнение команды ROLLBACK TRANSACTION или COMMIT TRANSACTION не прерывает работу триггера, поэтому следует внимательно отслеживать попытки многократного отката транзакции при выполнении разных условий.
Пример транзакции:
BEGIN TRAN
UPDATE account
SET balance= balance- 100
WHERE account_number=@s_account
If @@ error=0
BEGIN
ROLLBACK TRAN
RETURN
END
UPDATE card_account
SET balance=balance+100
WHERE account_number=@s_account
If @@ error=0
BEGIN
ROLLBACK TRAN
RETURN
END
COMMIT TRAN
Команда BEGIN TRAN сообщает серверу о начале транзакции. Это значит, что до получения сервером команды COMMIT TRAN все изменения являются временными. Следовательно, если на сервере произойдет сбой после первого обновления, произойдет откат транзакции. Никакой процесс не сможет получить доступ к данным до тех пор, пока не будет завершена транзакция.
5. Журнал транзакций.
Реализация принципа сохранения промежуточных состояний, подтверждения или отката транзакции обеспечивается специальным механизмом, для поддержки которого создана системная структура, называемая журналом транзакций. Журнал транзакций содержит последовательность записей об изменении БД. Он предназначен для обеспечения надежного хранения данных в БД. Это предполагает возможность восстановления согласованного состояния БД после любого рода аппаратных и программных сбоев. Общие принципы журнализации и восстановления:
· результаты зафиксированных транзакций должны быть сохранены в восстановленном состоянии БД;
· результаты незафиксированных транзакций не должны присутствовать в восстановленном состоянии БД.
Это означает, что восстанавливается последнее по времени согласованное состояние БД.
Возможны следующие ситуации, при которых требуется производить восстановление состояния БД:
· Восстановление после внезапной потери содержимого оперативной памяти (мягкий сбой). Такая ситуация может возникнуть в следующих случаях: при аварийном выключении электропитания или при возникновении неустранимого сбоя процессора. Ситуация характеризуется потерей той части базы данных, которая находилась к моменту сбоя в буферах оперативной памяти.
· Восстановление после поломки основного внешнего носителя БД (жесткий сбой).
Система должна обеспечивать восстановление как после небольших нарушений (например, после неудачно завершенных транзакций), так и после серьезных сбоев, (например сбоев питания, жестких сбоев).
При мягком сбое необходимо восстановить содержимое БД по содержимому журналов транзакций, хранящихся на дисках. При жестком сбое необходимо восстановить содержимое БД по архивным копиям и журналам транзакций, которые хранятся на неповрежденных внешних носителях.
Возможны два основных варианта ведения журнальной информации. В 1-м варианте для каждой транзакции поддерживается отдельный локальный журнал изменений БД этой транзакцией. Такие журналы называют локальными журналами. Они используются для локальных откатов транзакций. Кроме того, поддерживается общий журнал изменений БД, используемый для восстановления БД после мягких и жестких сбоев.
Этот подход позволяет быстро выполнять индивидуальные откаты транзакций, но приводит к дублированию информации в локальных и общем журналах. Поэтому чаще используют второй вариант – поддержание только общего журнала изменений БД, который используется и при выполнении индивидуальных откатов.
Общая структура журнала может быть представлена в виде некоторого последовательного файла, в котором фиксируется каждое изменение БД, происходящее в ходе выполнения транзакции. Все транзакции имеют внутренние номера, поэтому в журнале транзакций фиксируются все изменения, проводимые всеми транзакциями.
Каждая запись в журнале помечается номером транзакции, к которой она относится, и значениями атрибутов, которые она меняет, кроме того, для каждой транзакции в журнале фиксируется команда начала и завершения транзакции.
Для большей надежности журнал транзакций часто дублируется системными средствами СУБД, именно поэтому объем внешней памяти во много раз превышает реальный объем данных в базе.
Имеется 2 варианта ведения журнала транзакций: протокол с отложенными обновлениями и протокол с немедленными обновлениями.
Ведение журнала по принципу отложенных обновлений предполагает следующий механизм выполнения транзакций:
1. Когда транзакция Т1 начинается, в протокол заносится запись
Т1 Begin Transaction
2. На протяжении выполнения транзакции в протоколе для каждой изменяемой записи записывается новое значение
Т1.ID_RECORD, атрибут, новое значение
(ID_RECORD – уникальный номер записи)
3. Если все действия, из которых состоит транзакция, успешно выполнены, то транзакции частично фиксируется и в протокол заносится:
T1 COMMT
4. После того, как транзакция зафиксирована, записи протокола, относящиеся к Т1, используются для внесения изменений в БД.
5. Если происходит сбой, то СУБД просматривает протокол и выясняет, какие транзакции необходимо переделать. Транзакцию Т1 необходимо переделать, если протокол содержит обе записи Т1 Begin Transaction и T1 COMMT. БД может находиться в несогласованном состоянии, однако все новые значения измененных элементов данных содержатся в протоколе, и это требует повторного выполнения транзакции. Для этого используется системная процедура REDO(), которая заменяет все значения элементов данных на новые, просматривая протокол в прямом порядке.
6. Если в протоколе не содержится команда фиксации транзакции СOMMIT, то никаких действий проводить не требуется, а транзакция запускается заново.
Альтернативный механизм с немедленным выполнением предусматривает внесение изменений сразу в БД, а в протокол заносятся не только новые, но и все старые значения изменяемых атрибутов, поэтому каждая запись выглядит так:
Т1.ID_RECORD, атрибут, новое значение старое значение
При этом запись в журнал предшествует непосредственному выполнению операции над БД. Когда транзакция фиксируется, то есть встречается команда T1 COMMIT, и она выполняется, то все изменения оказываются уже внесенными в БД и не требуется никаких дальнейших действий по отношению к этой транзакции.
При откате транзакции выполняется системная процедура UNDO(), которая возвращает все старые значения в отмененной транзакции, последовательно проходя по протоколу, начиная с команды BEGIN TRANSACTION.
Для восстановления при сбое используется следующий механизм:
· Если транзакция содержит команду начала транзакции, но не содержит команду фиксации с подтверждением ее выполнения, то выполняется последовательность действий как при откате транзакции, то есть восстанавливаются старые значения.
На самом деле восстановление происходит по более сложным алгоритмам, т.к. изменения, как в журнал, так и в БД заносятся не сразу, а буферизуются. Журнализация изменений тесно связана не только с управлением транзакциями, но и с буферизацией страниц БД в оперативной памяти. Если бы запись об изменении БД, которая должна поступать в журнал при выполнении любой операции модификации БД, на самом деле немедленно записывалась во внешнюю память, это привело бы к существенному замедлению работы системы. Поэтому записи в журнале тоже буферизуются: при нормальной работе очередная страница выталкивается во внешнюю память журнала только при полном заполнении записями.
6. Блокировки.
В многопользовательских системах с одной базой данных одновременно могут работать несколько пользователей или прикладных программ. Одной из основных задач СУБД является обеспечение изолированности пользователей, то есть создание такого режима работы, чтобы каждому из пользователей казалось, что он работает с БД в одиночку. Такую задачу СУБД принято называть параллелизмом транзакций.
При параллельной обработке базы данных возникает три основных проблемы:
§ Пропавшие изменения. Эта ситуация возникает в тех случаях, когда 2 транзакции одновременно изменяют одну и ту же запись в БД. Например, работают 2 оператора на приеме заказов, первый оператор принял заказ на 30 мониторов. Когда он обращался на склад, то там числилось 40 мониторов, и он, получив подтверждение от клиента, оформил продажу 30 мониторов из 40. Параллельно с ним работает второй оператор, который принимает заказ на 20 таких же мониторов, и в свою очередь, обратившись на склад, он получает то же значение 40, и оформляет заказ для своего клиента. Заканчивая работу с данными, он выполняет команду Обновить, которая заносит 20 как остаток мониторов на складе. После этого первый оператор заканчивает работу со своим заказчиком и тоже выполняет команду Обновить, которая заносит остаток 10 как число мониторов, имеющихся на складе. В общей сложности они продали 50 мониторов при имеющихся 40, и при этом на складе будет числиться 10 мониторов.
§ Проблемы промежуточных данных. Связано с возможностью доступа к промежуточным данным. Допустим первый оператор, ведя переговоры со своим заказчиком, ввел заказанные 30 мониторов, но перед окончательным оформлением заказа клиент захотел выяснить еще некоторые характеристики товара. Приложение, с которым работает 1-й оператор, уже изменило остаток мониторов на складе, и там сейчас хранится информация о 10 оставшихся мониторах. В это время второй оператор пытается принять заказ от своего заказчика заказ на 20 мониторов, но его приложение показывает, что на складе осталось всего 10 мониторов и оператор вынужден отказать своему заказчику. В это время заказчик первого оператора принимает решение не покупать мониторы, оператор делает откат транзакции и на складе снова оказывается 40 мониторов. Такая ситуация стала возможной потому, что приложение второго оператора имело доступ к промежуточным данным, которые сформировало первое приложение.
§ Проблемы несогласованных данных. Связана с возможностью изменения данныx, уже прочитаныx другим приложением. Оба оператора начинают работать практически одновременно, получают начальное состояние склада 40 мониторов, а затем первый оператор продает своему заказчику 30 мониторов. Он завершает работу своего приложения, и оно выполняет команду фиксации транзакции COMMIT. Состояние БД непротиворечивое. В этот момент заказчик второго оператора решает сделать заказ и второй оператор, обращаясь повторно к данным, видит, что количество мониторов изменилось. Второй оператор считает, что нарушена целостность транзакции, т.к. в течение выполнения одной работы он получил 2 различных состояния склада. Эта ситуация возникла потому, что приложение 1-го оператора смогло изменить кортеж с данными, который уже прочитало приложение второго оператора.
Обобщая перечисленные проблемы, можно выделить следующие типы конфликтов между двумя параллельными транзакциями:
· W-W – транзакция 2 пытается изменить объект, измененный не закончившейся транзакцией 1;
· R-W – транзакция 2 пытается изменить объект, прочитанный не закончившейся транзакцией 1;
· W-R транзакция 2 пытается читать объект, измененный не закончившейся транзакцией 1;
7. Сериалиация транзакций
Для того чтобы избежать подобных конфликтов, требуется выработать некоторую процедуру согласованного выполнения параллельных транзакций. Эта процедуру должна удовлетворять следующим правилам:
1. В ходе выполнения транзакции пользователь видит только согласованные данные. Пользователь не должен видеть несогласованные промежуточные данные.
2. Когда в БД 2 транзакции выполняются параллельно, результаты выполнения транзакций должны быть такими же, как если бы выполнялась транзакция 1, а затем транзакция 2 или наоборот.
Процедура, обеспечивающая реализацию этих принципов, называется сериализацией транзакций. Она гарантирует, что каждый пользователь, обращаясь к БД, работает с ней так, как будто не существует других пользователей, одновременно обращающихся к тем же данным. Результат совместного выполнения транзакции эквивалентен результату некоторого последовательного выполнения этих же транзакций.
Самым простым выходом было бы последовательное выполнение транзакций, но такой выход неоптимален по времени, существуют более гибкие методы управления параллельным доступом к БД. Наиболее распространенный механизм решения этих проблем блокировка объекта (например, таблицы) на все время действия транзакции. Если транзакция обращается к заблокированному объекту, то она остается в состоянии ожидания до момента разблокировки этого объекта, после чего она может начать его обработку. Однако блокировка создает новые проблемы — задержку выполнения транзакций из-за блокировок.
Итак, блокировки, называемые также синхронизационными захватами объектов, могут быть применены к разному типу объектов. Наибольшим объектом блокировки может быть вся БД, однако этот вид блокировки сделает БД недоступной для всех других приложений, которые работают с данной БД. Следующий тип объекта блокировки – таблицы. Транзакция, которая работает с таблицей, блокирует ее на все время выполнения транзакции. Этот вид блокировки предпочтительнее предыдущего, потому что позволяет параллельно выполнять транзакции, которые работают с другими таблицами.
В ряде СУБД реализована блокировка на уровне страниц. В этом случае СУБД блокирует только отдельные страницы на диске, когда транзакция обращается к ним. Этот вид блокировки еще более мягок, и позволяет разным транзакциям работать с одной и той же таблице, если они обращаются к разным страницам данных.
В некоторых СУБД возможна блокировка на уровне строк, однако такой механизм блокировки требует дополнительных затрат, на свою поддержку. SQL Server стремится установить блокировку на уровне записей, чтобы обеспечить максимальную параллельность в работе. С увеличением количества блокировок строк сервер может перейти к блокировке страниц, если количество записей превышает пороговое значения.
8. Переопределение блокировок на уровне запроса. Типы блокировок
Если после имени таблицы в предложении FROM следует одно из перечисленных ключевых слов, запрос вмешивается в работу диспетчера блокировок и применяется заданный тип блокировки:
· NOLOCK- разрешает грязное чтение;
· PAGLOCK- блокировка на уровне страниц;
· ROWLOCK- блокировка на уровне записей;
· TABLOCK-разделяемая блокировка таблицы;
· TABLOCKX- монопольная блокировка таблицы
В настоящее время проблема блокировок является предметом большого числа исследований.
Различают два базовых типа блокировок (синхронизационных захватов):
Разделяемые (нежесткие) блокировки – это режим означает разделяемый захват объекта и используется для выполнения операции чтения объекта. Объекты, заблокированные таким образом, не изменяются в ходе выполнения транзакции и доступны другим транзакциям, но только в режиме чтения;
Монопольные (жесткие) блокировки – не позволяют вообще никому, кроме владельца этой блокировки, обращаться к данным. Эти блокировки используются для команд, которые изменяют содержание или структуру таблицы и действуют до конца транзакции.
Захваты объектов несколькими транзакциями по чтению совместимы, то есть нескольким транзакциям допускается читать один и тот же объект. Захват объекта одной транзакцией по чтению не совместим с захватом другой транзакцией того же объекта по записи. Захваты одного объекта разными транзакциями по записи не совместимы.
Однако применение разных типов блокировок приводит к проблеме тупиков. Проблема тупиков возникла при рассмотрении выполнения параллельных процессов в операционных средах и также была связана с управлением разделяемыми (совместно используемыми) объектами. Пример тупика: Пусть транзакция А жестко блокирует таблицу 1, а затем жестко блокирует таблицу 2. Транзакция В, наоборот жестко блокирует таблицу 2, а затем жестко блокирует таблицу 1.
Если обе эти транзакции начали работу одновременно, то после выполнения операций модификации первой таблицы они обе окажутся в бесконечном ожидании: транзакция А будет ждать завершения работы транзакции В и разблокировки таблицы 2, а транзакция В будет безрезультатно ждать завершения работы транзакции А и разблокировки таблицы 1.
Ситуации могут быть гораздо более сложными. Количество взаимно заблокированных транзакций может оказаться гораздо больше. Эту ситуацию каждая транзакция обнаружить самостоятельно не может. Ее должна разрешить СУБД. В большинстве коммерческих СУБД существует механизм обнаружения таких тупиковых ситуаций.
Основой обнаружения тупиковых ситуаций является построение (или постоянное поддержание) графа ожидания транзакций. Граф ожидания может представлять собой направленный граф, в вершинах которого расположены имена транзакций. Если транзакция Т1 ждет окончания транзакции Т2, то из вершины Т1 в вершину Т2 идет стрелка. Дополнительно стрелки могут быть помечены именами заблокированных объектов и типом блокировки.
В механизме реализации блокировок используется понятие уровня изоляции блокировки, определяющее, сколько таблиц будет блокировано. Традиционно используется три уровня изоляции:
· Уровень изоляции, называемый повторное чтение, реализует такую стратегию, что внутри данной транзакции все записи, извлеченные с помощью запросов, не могут быть изменены. Эти записи не могут быть изменены до тех пор, пока транзакция не завершиться.
· Уровень изоляции, который называют указатель стабильности, предохраняет каждую запись от изменений на время, когда она считывается, или от чтения на время ее изменения.
· Третий уровень стабильности, называется только чтение. Только чтение блокирует всю таблицу, а, следовательно, не может использоваться с командами модификации. Таким образом, только чтение гарантирует, что вывод запроса будет внутренне согласован с данными таблицы.
Итак, средство управления параллелизмом в СУБД определяет, то в какой степени, одновременно поданные команды будут мешать друг другу. В современных СУБД оно является адаптируемым средством, автоматически находящим оптимальное решение с учетом обеспечения максимальной производительности БД и доступности данных для действующих команд.
9. КОНТРОЛЬНЫЕ ВОПРОСЫ
1.Дайте определение транзакции. Приведите примеры транзакций.
2.Перечислите и охарактеризуйте свойства транзакций.
3.Какие возможны варианты завершения транзакций.
4.Какие операторы языка SQL служат для работы с транзакциями в расширенной модели транзакций?
5.Можно ли в триггерах использовать команды управления транзакциями?
6.Для чего предназначен журнал транзакций?
7.В каких случаях выполняется восстановление БД по журналу транзакций?
8.Какие варианты ведения журналов транзакций существуют?
9.В чем заключаются различия вариантов ведения журнала транзакций: протокола с отложенными обновлениями и протокола с немедленными обновлениями.
10. Какие проблемы возникают при параллельной работе пользователей с БД?
Люди также интересуются этой лекцией: 30. Денатурация белка.
11. Какие объекты БД могут быть заблокированы для реализации принципа изолированности пользователей?
12. Возможно ли задание вида блокировки в запросах?
13. Какие виды захвата объектов несколькими транзакциями существуют? Какие из них являются совместимыми?
14. В чем заключается проблема тупиков?
Транзакция (информатика) — это… Что такое Транзакция (информатика)?
Транза́кция (англ. transaction) — группа последовательных операций с базой данных, которая представляет собой логическую единицу работы с данными. Транзакция может быть выполнена либо целиком и успешно, соблюдая целостность данных и независимо от параллельно идущих других транзакций, либо не выполнена вообще и тогда она не должна произвести никакого эффекта. Транзакции обрабатываются транзакционными системами, в процессе работы которых создаётся история транзакций.
Различают последовательные (обычные), параллельные и распределённые транзакции. Распределённые транзакции подразумевают использование больше чем одной транзакционной системы и требуют намного более сложной логики (например, two-phase commit — двухфазный протокол фиксации транзакции). Также, в некоторых системах реализованы автономные транзакции, или под-транзакции, которые являются автономной частью родительской транзакции.
Пример транзакции
Пример: необходимо перевести с банковского счёта номер 5 на счёт номер 7 сумму в 10 денежных единиц. Этого можно достичь, к примеру, приведённой последовательностью действий:
- Начать транзакцию
- прочесть баланс на счету номер 5
- уменьшить баланс на 10 денежных единиц
- сохранить новый баланс счёта номер 5
- прочесть баланс на счету номер 7
- увеличить баланс на 10 денежных единиц
- сохранить новый баланс счёта номер 7
- Окончить транзакцию
Эти действия представляют собой логическую единицу работы «перевод суммы между счетами», и таким образом, являются транзакцией. Если прервать данную транзакцию, к примеру, в середине, и не аннулировать все изменения, легко оставить владельца счёта номер 5 без 10 единиц, тогда как владелец счета номер 7 их не получит.
Свойства транзакций
Основная статья: ACIDОдним из наиболее распространённых наборов требований к транзакциям и транзакционным системам является набор ACID (Atomicity, Consistency, Isolation, Durability). Вместе с тем, существуют специализированные системы с ослабленными транзакционными свойствами[1].
Уровни изоляции транзакций
В идеале транзакции разных пользователей должны выполняться так, чтобы создавалась иллюзия, что пользователь текущей транзакции — единственный. Однако в реальности, по соображениям производительности и для выполнения некоторых специальных задач, СУБД предоставляют различные уровни изоляции транзакций. Уровни описаны в порядке увеличения изоляции транзакций и надёжности работы с данными
- 0 — Неподтверждённое чтение (Read Uncommitted, Dirty Read, грязное чтение) — чтение незафиксированных изменений своей транзакции и параллельных транзакций, возможны нечистые, неповторяемые чтения и фантомы
- 1 — Подтверждённое чтение (Read Committed) — чтение всех изменений своей транзакции и зафиксированных изменений параллельных транзакций, нечистые чтения невозможны, возможны неповторяемые чтения и фантомы;
- 2 — Повторяемое чтение (Repeatable Read, Snapshot) — чтение всех изменений своей транзакции, любые изменения, внесённые параллельными транзакциями после начала своей, недоступны, нечистые и неповторяемые чтения невозможны, возможны фантомы;
- 3 — Упорядоченный — (Serializable, сериализуемый) — упорядоченные (сериализуемые) транзакции. Идентичен ситуации, при которой транзакции выполняются строго последовательно, одна после другой, то есть результат действия которых не зависит от порядка выполнения шагов транзакции (запрещено чтение всех данных, изменённых с начала транзакции, в том числе и своей транзакцией). Фантомы невозможны.
Чем выше уровень изоляции, тем больше требуется ресурсов, чтобы их поддерживать.
В СУБД уровень изоляции транзакций можно выбрать как для всех транзакций сразу, так и для одной конкретной транзакции. По умолчанию в большинстве баз данных используется уровень 1 (Read Committed). Уровень 0 используется в основном для отслеживания изменений длительных транзакций или для чтения редко изменяемых данных. Уровни 2 и 3 используются при повышенных требованиях к изолированности транзакций.
Реализация
Полноценная реализация уровней изоляции и свойств ACID представляет собой нетривиальную задачу. Обработка поступающих данных приводит к большому количеству маленьких изменений, включая обновление как самих таблиц, так и индексов. Эти изменения потенциально могут потерпеть неудачу: закончилось место на диске, операция занимает слишком много времени (timeout) и т. д. Система должна в случае неудачи корректно вернуть базу данных в состояние до транзакции.
Первые коммерческие СУБД (к примеру, IBM DB2), пользовались исключительно блокировкой доступа к данным для обеспечения свойств ACID. Но большое количество блокировок приводит к существенному уменьшению производительности. Есть два популярных семейства решений этой проблемы, которые снижают количество блокировок:
В обоих случаях, блокировки должны быть расставлены на всю информацию, которая обновляется. В зависимости от уровня изоляции и имплементации, блокировки записи также расставляются на информацию, которая была прочитана транзакцией.
При упреждающей журнализации, используемой в Sybase и MS SQL Server до версии 2005, все изменения записываются в журнал, и только после успешного завершения — в базу данных. Это позволяет СУБД вернуться в рабочее состояние после неожиданного падения системы. Теневые страницы содержат копии тех страниц базы данных на начало транзакции, в которых происходят изменения. Эти копии активизируются после успешного завершения. Хотя теневые страницы легче реализуются, упреждающая журнализация более эффективна[3]
Дальнейшее развитие технологий управления базами данных привело к появлению безблокировочных технологий. Идея контроля за параллельным доступом с помощью временных меток (timestamp-based concurrency control) была развита и привела к появлению многоверсионной архитектуры MVCC. Эти технологии не нуждаются ни в журнализации изменений, ни в теневых страницах. Архитектура, реализованная в Oracle 7.х и выше, записывает старые версии страниц в специальный сегмент отката, но они все ещё доступны для чтения. Если транзакция при чтении попадает на страницу, временная метка которой новее начала чтения, данные берутся из сегмента отката (то есть используется «старая» версия). Для поддержки такой работы ведётся журнал транзакций, но в отличие от «упреждающей журнализации», он не содержит данных. Работа с ним состоит из трёх логических шагов:
- Записать намерение произвести некоторые операции
- Выполнить задание, копируя оригиналы изменяемых страниц в сегмент отката
- Записать, что всё сделано без ошибок
Журнал транзакций в сочетании с сегментом отката (область, в которой хранится копия всех изменяемых в ходе транзакции данных) гарантирует целостность данных. В случае сбоя запускается процедура восстановления, которая просматривает отдельные его записи следующим образом:
- Если повреждена запись, то сбой произошёл во время проставления отметки в журнале. Значит, ничего важного не потерялось, игнорируем эту ошибку.
- Если все записи помечены как успешно выполненные, то сбой произошёл между транзакциями, здесь также нет потерь.
- Если в журнале есть незавершённая транзакция, то сбой произошёл во время записи на диск. В этом случае мы восстанавливаем старую версию данных из сегмента отката.
Firebird вообще не имеет ни журнала изменений, ни сегмента отката, а реализует MVCC, записывая новые версии строк таблиц прямо в активное пространство данных. Так же поступает MS SQL 2005. Теоретически это даёт максимальную эффективность при параллельной работе с данными, но ценой является необходимость «сборки мусора», то есть удаления старых и уже не нужных версий данных.
См. также
Примечания
- ↑ Advanced Transaction Models and Architectures (англ.)
- ↑ Семейство алгоритмов ARIES
- ↑ Gray, J., McJones, P., Blasgen, M., Lindsay, B., Lorie, R., Price, T., Putzolu, F., and Traiger, I. The recovery manager of the System R database manager. ACM Comput. Surv. 13, 2 (June 1981).
Определение бухгалтерской операции — AccountingTools
Что такое учетная операция?
Бухгалтерская операция — это бизнес-событие, оказывающее денежное влияние на финансовую отчетность предприятия. Это фиксируется в бухгалтерском учете предприятия. Примеры бухгалтерских операций:
Также могут иметь место мошеннические бухгалтерские операции, которые в основном совершаются руководством или бухгалтерией. Этих транзакций можно избежать за счет использования комплексной системы контроля.
Каждая бухгалтерская операция должна следовать требованиям уравнения бухгалтерского учета, которое гласит, что любая операция должна приводить к активам, равным обязательствам плюс акционерный капитал. Например:
Продажа покупателю приводит к увеличению дебиторской задолженности (актива) и увеличению выручки (косвенно увеличивает акционерный капитал).
Покупка у поставщика приводит к увеличению расходов (косвенно уменьшает собственный капитал) и уменьшению денежных средств (актива).
Получение денежных средств от покупателя приводит к увеличению денежных средств (актива) и уменьшению дебиторской задолженности (актива).
Заимствование средств у кредитора приводит к увеличению денежных средств (актива) и увеличению кредиторской задолженности (обязательств).
Таким образом, каждая бухгалтерская операция приводит к сбалансированному бухгалтерскому уравнению.
Бухгалтерские операции прямо или косвенно записываются в журнале. Косвенное разнообразие создается, когда вы используете модуль в бухгалтерском программном обеспечении для записи транзакции, и модуль создает запись журнала для вас.Например, модуль выставления счетов в бухгалтерском программном обеспечении будет дебетовать счет дебиторской задолженности и кредитовать счет доходов каждый раз, когда вы создаете счет-фактуру клиента.
Если запись журнала создается непосредственно в системе учета вручную, убедитесь, что сумма всех дебетований равна сумме всех кредитов, в противном случае транзакция будет несбалансированной, что сделает невозможным создание финансовой отчетности. Если запись журнала создается непосредственно в программном пакете бухгалтерского учета, программа откажется принять запись, если не будет списано равное количество кредитов.
Сопутствующие курсы
Учебный комплект для бухгалтеров
Справочник по бухгалтерскому учету
Отличные примеры бухгалтерских операций! (Дебет и кредит)
В этом руководстве представлены примеры бухгалтерских операций и записей журнала, наиболее распространенных для малых предприятий. Это также объясняет , почему мы дебетуем и кредитуем счета, которые мы ведем .
○ Это руководство содержит партнерские ссылки. Прочтите нашу политику раскрытия информации, чтобы узнать больше. ○Основы бухгалтерского учета, которые следует запомнить
Прежде чем рассматривать наши образцы транзакций, давайте сделаем обзор.При записи транзакции или записи в журнале в бухгалтерском программном обеспечении, таком как QuickBooks или Sage Accounting (Peachtree), одна учетная запись дебетуется, а другая — кредитуется. В некоторых случаях два счета могут получать дебет или кредит. Но общая сумма дебета должна равняться общей сумме кредита .
В некоторых случаях, например, при выписке чека в QuickBooks, программа знает, нужно ли кредитовать (вычитать из) наличные, поэтому вам нужно только знать, какой счет, часто это расходный счет, должен получать дебет.Но нужно знать, какие счета дебетовать и кредитовать при публикации журнальных записей. Итак, давайте посмотрим на несколько супер-образцов транзакций!
Пример 1: Владелец инвестирует капитал в компанию
Владелец инвестирует 5000 долларов. Анализ: Поскольку деньги зачисляются на текущий счет, наличные списываются (баланс увеличивается на 5000 долларов). На какой счет поступает кредит? Акционерный счет под названием «Собственный капитал» или «Вклад в капитал». Поскольку счета Equity являются «отрицательными», кредитование этого счета Equity увеличивает его баланс на 5000 долларов США.
Дебетовая касса (увеличить остаток)
Собственный капитал (увеличивает остаток)
Пример 2: Компания берет ссуду
Компания занимает в банке 8000 долларов. Анализ: поскольку деньги будут зачислены на текущий счет, денежные средства дебетуются (остаток увеличивается на 8000 долларов). Счет для получения кредита — это счет пассивов, который называется «Ссуды к оплате» (вы можете создать отдельный счет или субсчет для каждого заем).Счета пассивов являются кредитными, поэтому при зачислении на счет пассивов его отрицательный баланс увеличивается на 8000 долларов (смещение влево на числовой строке).
Дебетовая наличность (увеличивает остаток)
Кредитная задолженность по кредитам (увеличивает остаток)
Пример 3: Ежемесячная комиссия за выписку из банка
Ваш банк взимает ежемесячную комиссию за выписку в размере 14 долларов США. Анализ: Эта транзакция вводится через запись журнала каждый месяц, когда текущий счет сбалансирован.Поскольку деньги были сняты с текущего счета, зачисляются наличные (остаток уменьшился на 14 долларов). Счет расходов, называемый «Платежи за банковские услуги», получает дебет.
Дебетовая комиссия банка (увеличивает баланс)
Кредит наличными (уменьшает остаток)
Учебник KeynoteSupport.com
Пример 4: Выплата ссуды
Вы платите 540 долларов чеком по ссуде на 8000 долларов, полученной в Примере 2. Из этой суммы 500 долларов применяется к основной сумме, а 40 долларов — к процентам по ссуде.
Анализ: Поскольку выписывается чек, QuickBooks автоматически зачисляет наличные. В этом случае дебет делится между двумя счетами . Чтобы отразить 500 долларов, которые были применены к остатку ссуды, дебетуйте ссудный счет. (Так как это пассивный счет, дебет уменьшит его баланс, что вы и хотите.) Выплаченные проценты в размере 40 долларов являются расходами, поэтому дебетуйте счет расходов, называемый процентами по ссуде. Помните, что даже если дебет разделен между двумя счетами, общий дебет всегда должен равняться общему кредиту .
Дебетовая кредиторская задолженность 500 $ (уменьшает остаток)
Дебетовые процентные расходы 40 долларов (увеличивает остаток)
Кредит наличными $ 540 (уменьшает остаток)
Пример 5: Компания выписывает чек на оплату актива
Компания выписывает чек на оборудование на 8 500 долларов. Анализ: Поскольку был выписан чек, QuickBooks автоматически зачисляет наличные. Товар слишком дорог, чтобы считаться расходом, поэтому его необходимо ввести в систему бухгалтерского учета как актив .Итак, мы будем дебетовать счет актива под названием «Оборудование» или что-то подобное.
Кроме того, активы должны амортизироваться с течением времени, и записи в журнале должны вводиться каждый год в течение запрещенного количества лет. Амортизация — это сложный процесс, поэтому при покупке активов компании обязательно обратитесь к своему бухгалтеру.
Debit Equipment (увеличивает баланс)
Кредит наличными (уменьшает остаток)
[Помните: дебет добавляет положительное число, а кредит добавляет отрицательное число.Но мы НИКОГДА не ставим минус на число, которое вводим в бухгалтерское программное обеспечение.]
Пример 6: Компания выписывает чек для оплаты расходов
Компания выписывает чек на оплату канцелярских товаров на 318 долларов. Анализ: Поскольку был выписан чек, QuickBooks автоматически зачисляет наличные. Мы дебетуем счет расходов под названием «Офис».
Дебетовая касса (увеличивает остаток)
Кредит наличными (уменьшает остаток)
Пример 7: Компания использует кредитную карту для оплаты расходов
Компания покупает канцелярские товары на сумму 318 долларов США и производит оплату с помощью кредитной карты компании.Вернувшись в офис, счет вводится в бухгалтерскую программу. Анализ: Когда вы вводите счет, QuickBooks автоматически кредитует счет пассивов под названием «Счета к оплате». А так как вы приобрели канцелярские товары, дебет должен поступить на счет расходов под названием «Офис» (или аналогичный).
Дебетовая касса (увеличить остаток)
Кредиторская задолженность (увеличивает остаток)
Пример 8: Компания оплачивает счет по кредитной карте
Вы оплачиваете счет за канцелярские товары на 318 долларов, купленные в Примере 7.Анализ: Когда был введен счет, был дебетован счет расходов под названием «Офис» (или аналогичный) и кредиторская задолженность. Теперь, когда мы выписываем чек для оплаты счета, QuickBooks автоматически зачисляет наличные. И бухгалтерское программное обеспечение будет списывать счеты с кредиторской задолженности, фактически аннулируя ранее полученный кредит.
Дебетовая кредиторская задолженность (уменьшает остаток)
Кредит наличными (уменьшить остаток)
Пример 9: Компания платит наличными за хорошо проданную стоимость (COGS)
Компания платит 450 долларов наличными за Продукт A — часть COGS.Анализ: когда вы выписываете чек, QuickBooks автоматически зачисляет наличные. В окне проверки выберите учетную запись COGS на вкладке «Расходы» или выберите элемент на вкладке «Элементы», связанный с учетной записью COGS. В любом случае счет COGS получает дебет.
Дебетовая COGS (увеличить остаток)
Кредит наличными (уменьшить остаток)
Пример 10: Компания получает оплату наличными за продажу
Компания продает Продукт А за 650 долларов наличными.Анализ: Когда вы вводите продажу за наличные, QuickBooks автоматически дебетует наличные. Вам нужно будет выбрать Предмет для продажи… это может быть «Доход от продукта A» и связанный с учетной записью Продажи.
Дебетовая наличность (увеличивает остаток)
Продажа в кредит (увеличивает баланс)
Учебник KeynoteSupport.com
Пример 11: Компания продает кредитную карту
Компания продает Продукт А за 650 долларов в кредит.Анализ: при создании счета-фактуры необходимо указать Позиция для каждого отдельного платежа в счете-фактуре. QuickBooks автоматически зачислит на счет доходов, связанных с этими Предметами. QuickBooks автоматически дебетует сумму счета на счет дебиторской задолженности.
Дебетовые счета Дебиторская задолженность (увеличивает остаток)
Продажа в кредит (увеличивает остаток)
Пример 12: Компания получает платеж по счету
Компания получает платеж по счету на 650 долларов, указанному выше.Анализ: Когда вы создали счет, QuickBooks дебетовал счет дебиторской задолженности. Когда вы проводите оплату счета-фактуры, QuickBooks кредитует A / R — по сути, аннулируя более раннее дебетование. Программное обеспечение для бухгалтерского учета также будет списывать наличные, увеличивая свой баланс.
Дебетовая наличность (увеличивает остаток)
Кредит A / R (уменьшает остаток)
Пример 13: Владелец забирает деньги из компании — распределение
Владелец выписывает себе чек на 1000 долларов.Анализ: Поскольку был выписан чек, QuickBooks автоматически зачисляет наличные. Счет, который вы выбрали для дебетования, — это счет капитала, который называется Draw (Sole Proprietor) или Distribution (Corporation). Примечание. Это единственные внеплановые счета капитала, которые являются положительными и получают дебет.
Дебетовый тираж владельца (увеличивает его остаток)
Кредит наличными (уменьшить остаток)
Мы надеемся, что этот учебник по супервыборочным учетным транзакциям оказался полезным.Ваше здоровье!
Заявление об ограничении ответственности : Служба поддержки Keynote предоставляет посетителям общую информацию в удобочитаемом формате. Мы приложили все усилия, чтобы предоставить точную информацию на дату публикации этой статьи. Каждая клиентская среда и каждая транзакция уникальны, поэтому используйте информацию и примеры в этой статье только в качестве руководства. Нет никаких гарантий, что эти примеры транзакций будут иметь отношение к среде читателя.Кроме того, читатель не может сделать вывод из этой статьи, что служба поддержки Keynote предоставляет финансовые или бухгалтерские консультации. Проконсультируйтесь со специалистом в области финансов или бухгалтерского учета для получения помощи в соответствии с вашими уникальными требованиями.
↑ Вернуться к началу
Учетная операция — определение, примеры, виды
Определение бухгалтерских операций
Бухгалтерская операция — это хозяйственная деятельность или операция, которая оказывает денежное влияние на финансовую отчетность компании.Например, Apple, отражающая в своем балансе около 200 миллиардов долларов наличными и их эквивалентами, является бухгалтерской транзакцией. Учет таких операций основан на фундаментальном уравнении бухгалтерского учета: Актив = Обязательства + Собственный капитал.
Примеры бухгалтерских операций
Пример # 1
Кэти владеет цветочным магазином и, чтобы расширить свой бизнес за счет доставки, она купила подержанный автофургон стоимостью 30 000 долларов. Она произвела оплату наличными продавцу.Обратите внимание на записи в ее бухгалтерской книге.
Решение:
Пример # 2
Теперь, с тем же примером, представьте, что Кэти наняла сотрудника 1 января 2019 года с ежемесячной заработной платой в 000 000 на 1 -й день следующего месяца. Общий объем продаж в январе составил 30 000 долларов. Однако ее клиенты заплатили только 22 000 долларов наличными (включая 6000 долларов в качестве авансовых платежей), и 8 000 долларов должны были быть получены от них после доставки в феврале.Можете ли вы помочь Кэти записать эти транзакции в ее бухгалтерские книги за январь?
Решение:
Давайте посмотрим, какие записи мы можем сделать для Кэти:
* Оплачивается наличными 1 февраля.
Типы
Есть два типа бухгалтерских операций — внутренние и внешние.
Вы можете свободно использовать это изображение на своем веб-сайте, в шаблонах и т. Д. Пожалуйста, предоставьте нам ссылку с указанием авторства Ссылка на статью с гиперссылкой
Например:
Источник: Бухгалтерские операции (wallstreetmojo.com)
Внешние транзакции : Подобные транзакции происходят между двумя компаниями или организациями. Поскольку это внутрихолдинговая транзакция; следовательно, он включает денежный обмен или обмен активами. Покупка товара или привлечение долга у кредиторов — это своего рода пример внешних сделок.
Если компания покупает основной актив, как правило, она не учитывает общую стоимость актива в качестве расходов, даже если компания приобрела этот актив наличными авансом.Ниже будет учитываться актив, который был приобретен авансом.
Основные средства | (дебет) 100000 долларов |
Наличные | (кредит) 100,00 долларов |
Приведенная выше запись журнала является примером внешней бухгалтерской операции.
Внутренние транзакции : Они включают процессы внутри организации, например, путем уменьшения стоимости актива путем его ежегодной амортизации.
После того, как компания купила актив, она будет амортизировать его стоимость в каждом периоде, и только эта сумма амортизации будет считаться расходом в отчете о прибылях и убытках. Таким образом, после годового журнала запись об амортизации этого актива будет выглядеть, как показано ниже:
Основные средства | 100000 долларов США |
(-) Амортизация | 10,00 долларов США |
Чистые основные средства | 90 000 долларов США |
Эти 10 000 долларов будут отражены в отчете о прибылях и убытках до EBIT как расходы.Поскольку эта запись является только учетной записью, а не фактическим денежным переводом, она называется внутренней транзакцией.
Рекомендуемые статьи
Это руководство по бухгалтерской операции и ее определению. Здесь мы обсуждаем эти два типа вместе с практическими примерами. Подробнее о бухгалтерском учете вы можете узнать из следующих статей —
учетных операций — обзор, типы, двойная запись
Что такое бухгалтерские операции?
Бухгалтерские операции относятся к любой хозяйственной деятельности, которая оказывает прямое влияние на финансовое состояние и финансовую отчетность Три финансовых отчета Три финансовых отчета — это отчет о прибылях и убытках, баланс и отчет о движении денежных средств.Эти три основных заявления касаются бизнеса. Такие операции бывают разных форм, в том числе:
- Продажа наличными и в кредит клиентам
- Получение денежных средств от покупателя путем отправки счета
- Покупка основных средств Материальные активы Материальные активы — это активы с физической формой и удерживаемой стоимостью. Примеры включают основные средства. Материальные активы — это и движимые активы
- Займ средств у кредитора
- Погашение заемных средств у кредитора
- Выплата денежных средств поставщику из отправленного счета
Обязательно помнить, что каждый Сделка должна показывать баланс между активами и обязательствами Типы обязательств Существует три основных типа обязательств: краткосрочные, долгосрочные и условные обязательства.Обязательства — это юридические обязательства или долг, или дебет и кредит, так что получение денежных средств от покупателя равно увеличению выручки или что покупка у поставщика равна увеличению расходов и уменьшению денежных средств.
Типы бухгалтерских операций на основе институциональных отношений
Типы бухгалтерских операций могут основываться на различных точках зрения. Первое, что мы обсудим, — это типы бухгалтерских операций в соответствии с институциональными отношениями, а именно внешние и внутренние операции.
1. Внешние операции
Сюда входит торговля товарами и услугами за деньги. Таким образом, можно сказать, что любая транзакция, заключаемая двумя лицами или двумя организациями Типы организаций В этой статье о различных типах организаций исследуются различные категории, к которым могут относиться организационные структуры. Организационные структуры, в которых одна покупка, а другая продажа, считается внешней сделкой. Это также называется бизнес-транзакцией.
Пример: если компания A покупает сырье для своего производства у компании B, то это называется внешней транзакцией.
2. Внутренние транзакции
Они связаны не с продажами, а с другими процессами внутри организации. Это может включать расчет заработной платы сотрудников и оценку амортизационной стоимости определенного актива.
Типы учетных операций, основанных на обмене наличными
На основе обмена наличными деньгами существует три типа бухгалтерских операций, а именно кассовые операции, безналичные операции и кредитные операции.
1. Операции с наличными деньгами
Это наиболее распространенные формы операций, которые относятся к операциям с наличными деньгами. Например, если компания покупает канцелярские товары и оплачивает их наличными, дебетовой картой или чеком, то это транзакция наличными.
2. Безналичные операции
Они не связаны с операциями, в которых указывается, были ли выплачены наличные деньги или они будут выплачены в будущем. Например, если компания A покупает машину у компании B и видит, что она неисправна, ее возврат не повлечет за собой потраченных денежных средств, поэтому он подпадает под безналичные операции.Другими словами, транзакции, которые не являются наличными или кредитными, являются безналичными транзакциями.
3. Кредитные операции
Это отложенные кассовые операции, поскольку платеж обещан и завершен в будущем. Компании часто продлевают условия кредита для оплаты, например 30 дней, 60 дней или 90 дней, в зависимости от продаваемого продукта или услуги или отраслевых норм.
Типы бухгалтерских операций на основе цели
Существует два типа бухгалтерских операций, основанных на цели, а именно: коммерческие и некоммерческие.
1. Бизнес-операции
Это повседневные операции, которые поддерживают бизнес, такие как продажи и покупки, аренда офисных помещений, реклама и другие расходы.
2. Некоммерческие операции
Это операции, которые не связаны с продажей или покупкой, но могут включать пожертвования и социальную ответственность.
3. Личные транзакции
Личные транзакции — это транзакции, которые выполняются в личных целях, например, для покрытия расходов на день рождения.
Учет бухгалтерских операций с двойной записью
При записи бухгалтерских операций метод двойной записи — это системный учет, при котором для каждой записи в счет требуется противоположная запись в другой счет, дающий сальдированные записи журнала. Двусторонняя запись в журнале состоит из двух равных и соответствующих сторон, известных как дебет (слева) и кредит (справа). Это гарантирует, что общая сумма дебетов всегда будет равна общей сумме кредитов.
Ссылки по теме
CFI является официальным поставщиком услуг глобального аналитика финансового моделирования и оценки (FMVA). Стать сертифицированным аналитиком финансового моделирования и оценки (FMVA) ® Сертификация CFI по анализу финансового моделирования и оценки (FMVA) ® поможет вам получить необходимую уверенность в своей финансовой карьере.Зарегистрируйтесь сегодня! ® Станьте сертифицированным аналитиком по финансовому моделированию и оценке (FMVA) ® Сертификат CFVA (FMVA) ® поможет вам обрести уверенность в своей финансовой карьере. Запишитесь сегодня! программа сертификации, призванная помочь любому стать финансовым аналитиком мирового уровня. Чтобы продолжить продвижение по карьерной лестнице, вам будут полезны следующие дополнительные ресурсы CFI:
- Теория финансового учета Теория финансового учета Теория финансового учета объясняет, почему стоит учет — причины, по которым транзакции сообщаются определенным образом.Это руководство будет
- Руководство по записям в журнале капитал, основные средства, заемный капитал и чистая прибыль. В этом руководстве подробно рассказывается, как рассчитать
- Прогнозирование статей отчета о прибылях и убытках Прогнозирование статей отчета о прибылях и убыткахПрогнозирование отдельных статей отчета о прибылях и убытках начинается с выручки от продаж, затем начинается стоимость
Базовая учетная операция с ПРИМЕРАМИ
Что такое учетная операция?
Бухгалтерская операция — это событие, которое влияет на финансовую отчетность предприятия. В этом руководстве мы узнаем, как основные транзакции проходят через уравнение бухгалтерского учета. Что нам нужно помнить, так это то, что поскольку уравнение бухгалтерского учета всегда уравновешивает, каждому движению в уравнении должно противодействовать другое движение на ту же величину.
Теперь вот как выглядят счета пекарни прямо сейчас:
АКТИВЫ | ОБЯЗАТЕЛЬСТВА | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Банк 20 000 долларов | Займ 9 000 долларов | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Компьютер КАПИТАЛ ВЛАДЕЛЬЦА 15000 долларов | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
iPhone 500 долларов | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Баланс 24000 долларов | Баланс 24000 долларов , наша любимая печь Bakemaster серии X стоимостью 2000 долларов и iPhone, который мы забили на eBay за 500 долларов.Справа у нас есть единственное обязательство, которое представляет собой ссуду от Анны в банке на сумму 9000 долларов. Баланс состоит из собственного капитала в размере 15 000 долларов США. Обратите внимание, как дебетовая сторона и кредитная сторона сбалансированы друг с другом , поскольку в сумме они составляют 24 000 долларов. Хорошее начало. Пришло время заняться делом. Ниже приведены некоторые повседневные операции из жизни вашей пекарни. Начнем продавать торты! Осуществление транзакции 1Вы покупаете смесь для торта для своего магазина за 3000 долларов. Покупка нашей знаменитой смеси для тортов похожа на покупку инвентаря.На данный момент мы собираемся классифицировать закупку запасов как расход . Следовательно, наши расходов увеличатся. Помните, это приведет к увеличению дебетовой стороны на . Итак, теперь, когда расходы (CAKE MIX) увеличились на дебетовой стороне, необходимо еще одно движение, чтобы сбалансировать уравнение. Другая сторона нашей транзакции должна быть либо:
В этом случае, поскольку мы тратим деньги на покупку смеси для торта, движение очевидно уменьшение нашего банковского счета на 3000 долларов. Следовательно, транзакция будет выглядеть так:
Обратите внимание, как наша дебетовая сторона увеличилась на 3000 долларов из-за увеличения расходов на Cake Mix.Затем наша дебетовая сторона уменьшилась на 3000 долларов, потому что наш банковский счет, актив, уменьшился, когда мы заплатили за смесь для торта. В результате обе записи нейтрализуют друг друга, и наше уравнение остается в равновесии. Идеальный! Пример транзакции 2Энн звонит кредитный специалист. Она просит выплатить проценты по кредиту в размере 1000 долларов. Хорошо, мы имеем дело с расходом, а именно с процентами. Мы знаем, что расходы относятся к дебету. Это означает, что мы зарегистрируем процентные расходы в размере 1000 долларов США. Для выплаты процентов мы сняли деньги с банковского счета, поэтому другой стороной уравнения будет уменьшение нашего банковского счета на 1000 долларов. Посмотрим, как он уравновешивается.
Пример транзакции 4Hint4 Вы оплачиваете счет за телефонный звонок — Вы оплачиваете счет за телефонный звонок в размере долларов США. .Расходы относятся на дебетовую сторону. Для оплаты телефонного счета потребуется снять деньги в БАНКЕ.
Транзакция 5:
Проблема транзакции 6Вы слишком долго играли со страницей пекарни на Facebook, и компьютер перегревается.Вы платите мастеру по ремонту 50 долларов, чтобы починить его. Подсказка — РЕМОНТ — это расходы. Расходы относятся на дебетовую сторону. Для оплаты расходов необходимо взять деньги в БАНКЕ.
Операционное упражнение 7Пора в отпуск. Может быть, на Гавайях? Вы снимаете 1000 долларов с банковского счета пекарни, чтобы купить билет. Подсказка — когда владелец снимает деньги по личным причинам, это считается ЧЕРТЕЖАМИ. Чертежи находятся на дебетовой стороне.
Транзакция 8:Вы посетите магазин автомобилей Johns, чтобы купить автомобиль доставки. Вы выбираете розового жука с желтым горошком и большим цветком посередине.Стоит 3000 долларов. Вы покупаете автомобиль в кредит, то есть полностью оплатите его в следующем месяце. Подсказка — CAR является активом. Активы относятся к дебету. Когда вы покупаете что-то в кредит, это похоже на долг. Вы должны деньги, что является обязательством. Обязательства находятся на стороне кредита.
У нас было восемь новых транзакций, проведенных через наш бизнес.Давайте посмотрим, как теперь выглядят наши счета: Приведенная ниже таблица — это просто расширенная версия нашего бухгалтерского уравнения. Обратите внимание, что слева у нас все еще есть активы, расходы и чертежи. Справа у нас есть выручка, обязательства и собственный капитал.
|