Oracle поддерживает очень мощную и надежную модель транзакций. Код приложения определяет логическую последовательность выполняемых операций, результаты которой должны быть либо сохранены командой
COMMIT
, либо отменены командой ROLLBACK.
Транзакция начинается неявно с первой команды SQL
, выполняемой после команды COMMIT
или ROLLBACK
(или с начала сеанса) или же после команды ROLLBACK TO SAVEPOINT
. Для управления транзакциями PL/SQL
предоставляет набор команд:
COMMIT
— сохраняет (фиксирует) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK
— отменяет (откатывает) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK TO SAVEPOINT
— отменяет все изменения со времени установки последней точки сохранения и снимает все блокировки, установленные в этой части кода.- SAVEPOINT — устанавливает точку сохранения, после чего становится возможным частичный откат транзакции.
SET TRANSACTION
— позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката.LOCK TABLE
— позволяет заблокировать всю таблицу в указанном режиме. (По умолчанию к таблице обычно применяется блокировка на уровне строк.)
Эти команды более подробно рассматриваются в следующих разделах блога.
Команда COMMIT
Фиксирует все изменения, внесенные в базу данных в ходе сеанса текущей транзакцией. После выполнения этой команды изменения становятся видимыми для других сеансов или пользователей. Синтаксис этой команды:
COMMIT [WORK] [COMMENT текст];
Ключевое слово WORK
не обязательно — оно только упрощает чтение кода.
Ключевое слово COMMENT
также не является обязательным; оно используется для задания комментария, который будет связан с текущей транзакцией. Текстом комментария должен быть заключенный в одинарные кавычки литерал длиной до 50 символов. Обычно комментарии задаются для распределенных транзакций с целью облегчения их анализа и разрешения сомнительных транзакций в среде с двухфазовой фиксацией. Они хранятся в словаре данных вместе с идентификаторами транзакций.
Обратите внимание: команда COMMIT
снимает все блокировки таблиц, установленные во время текущего сеанса (например, для команды SELECT FOR UPDATE
). Кроме того, она удаляет все точки сохранения, установленные после выполнения последней команды COMMIT
или ROLLBACK
.
После того как изменения будут закреплены, их откат становится невозможным.
Все команды в следующем фрагменте являются допустимыми применениями COMMIT
:
COMMIT;
COMMIT WORK;
COMMIT COMMENT 'maintaining account balance'.
Команда ROLLBACK
Команда ROLLBACK
отменяет (полностью или частично) изменения, внесенные в базу данных в текущей транзакции. Для чего это может потребоваться? Например, для исправления ошибок:
DELETE FROM orders;
«Нет, Нет! Я хотел удалить только те заказы, которые были сделаны до мая 2005 года!» Нет проблем — достаточно выполнить команду ROLLBACK. Что касается программирования приложений, в случае возникновения проблем откат позволяет вернуться к исходному состоянию.
Синтаксис команды ROLLBACK
:
ROLLBACK [WORK] [TO [SAVEPOINT] имя_точки_сохранения];
Существует две основные разновидности ROLLBACK
: без параметров и с секцией TO, указывающей, до какой точки сохранения следует произвести откат. Первая отменяет все изменения, выполненные в ходе текущей транзакции, а вторая отменяет все изменения и снимает все блокировки, установленные после заданной точки сохранения. (О том, как установить в приложении точку сохранения, рассказано в следующем разделе.) Имя точки сохранения представляет собой необъявленный идентификатор Oracle
. Это не может быть литерал (заключенный в кавычки) или имя переменной.
Все команды ROLLBACK
в следующем фрагменте действительны :
ROLLBACK;
ROLLBACK WORK;
ROLLBACK TO begin_cleanup;
При откате до заданной точки сохранения все установленные после нее точки стираются, но данная точка остается. Это означает, что можно возобновить с нее транзакцию и при необходимости снова вернуться к этой же точке сохранения.
Непосредственно перед выполнением команды INSERT
, UPDATE
, MERGE
или DELETE PL/SQL
автоматически устанавливает неявную точку сохранения, и если команда завершается ошибкой, выполняется автоматический откат до этой точки. Если в дальнейшем в ходе выполнения команды DML происходит сбой, выполняется автоматический откат до этой точки. Подобным образом отменяется только последняя команда DML
.
Команда SAVEPOINT
Устанавливает в транзакции именованный маркер, позволяющий в случае необходимости выполнить откат до отмеченной точки сохранения. При таком откате отменяются все изменения и удаляются все блокировки после этой точки, но сохраняются изменения и блокировки, предшествовавшие ей. Синтаксис команды SAVEPOINT
:
SAVEPOINT имя_точки_сохранения;
Здесь имя точки сохранения — необъявленный идентификатор. Он должен соответствовать общим правилам формирования идентификаторов Oracle (до 30 символов, начинается с буквы, состоит из букв, цифр и символов #, $ и _), но объявлять его не нужно (да и невозможно).
Область действия точки сохранения не ограничивается блоком PL/SQL, в котором она установлена. Если в ходе транзакции имя точки сохранения используется повторно, эта точка просто «перемещается» в новую позицию, причем независимо от процедуры, функции или анонимного блока, в котором выполняется команда SAVEPOINT
. Если точка сохранения устанавливается в рекурсивной программе, на самом деле на каждом уровне рекурсии она задается заново, но откат может быть возможен только к одной точке — той, что установлена последней.
Команда SET TRANSACTION
Команда SET TRANSACTION
позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката. Эта команда должна быть первой командой SQL
транзакции и дважды использоваться в ходе одной транзакции не может. У нее имеются четыре разновидности.
-
SET TRANSACTION READ ONLY
— определяет текущую транзакцию доступной «только для чтения». В транзакциях этого типа всем запросам доступны лишь те изменения, которые были зафиксированы до начала транзакции. Они применяются, в частности, в медленно формируемых отчетах со множеством запросов, благодаря чему в них часто используются строго согласованные данные. -
SET TRANSACTION READ WRITE
— определяет текущую транзакцию как операцию чтения и записи данных в таблицу. SET TRANSACTION ISOLATION LEVEL SERIALIZABLE | READ COMMITTED
— определяет способ выполнения транзакции, модифицирующей базу данных. С ее помощью можно задать один из двух уровней изоляции транзакции:SERIALIZABLE
илиREAD COMMITTED
. В первом случае командеDML
, пытающейся модифицировать таблицу, которая уже изменена незафиксированной транзакцией, будет отказано в этой операции. Для выполнения этой команды в инициализационном параметре COMPATIBLE базы данных должна быть задана версия 7.3.0 и выше.При установке уровняREAD COMMITED
командаDML
, которой требуется доступ к строке, заблокированной другой транзакцией, будет ждать снятия этой блокировки.SET TRANSACTION USE ROLLBACK SEGMENT
имя сегмента — назначает текущей транзакции заданный сегмент отката и определяет ей доступ «только для чтения». Не может использоваться совместно с командойSET TRANSACTION READ ONLY
.
Механизм сегментов отката считается устаревшим; вместо него следует использовать средства автоматического управления отменой, введенные в Oracle9i.
Команда LOCK TABLE
Команда блокирует всю таблицу базы данных в указанном режиме. Блокировка запрещает или разрешает модификацию данных таблицы со стороны других транзакций на то время, пока вы с ней работаете. Синтаксис команды LOCK TABLE
:
LOCK TABLE
список_таблиц IN режим_блокировки MODE [NOWAIT];
Здесь список таблиц — список из одной или нескольких таблиц (локальных таблиц/пред- ставлений или доступных через удаленное подключение), а режим блокировки — один из шести режимов: ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE.
Если команда содержит ключевое слово NOWAIT
, база данных не ждет снятия блокировки в том случае, если нужная таблица заблокирована другим пользователем, и выдает сообщение об ошибке. Если ключевое слово NOWAIT
не указано, Oracle ждет освобождения таблицы в течение неограниченно долгого времени. Блокировка таблицы не мешает другим пользователям считывать из нее данные.
Примеры допустимых команд LOCK TABLE
:
LOCK TABLE emp IN ROW EXCLUSIVE MODE;
LOCK TABLE emp, dept IN SHARE MODE NOWAIT;
LOCK TABLE scott.emp@new_york IN SHARE UPDATE MODE;
Там, где это возможно, используйте стандартные средства блокировки Oracle
. Команду LOCK TABLE
в приложениях следует использовать только в крайних случаях и с величайшей осторожностью.
Вас заинтересует / Intresting for you:
20. Обработка транзакций
20.1. Что такое транзакция
Транзакции представляют собой блоки из операторов SQL, которые должны выполняться в пакетном режиме.
Обработка транзакций обеспечивает сохранение целостности базы данных за счет того, что пакеты операций SQL полностью или не выполняются вовсе.
Рассмотрим процесс добавления нового заказа по этапам.
1. Проверка, содержится ли информация о клиенте в базе данных. Если нет, такая информация добавляется.
2. Выборка идентификатора клиента.
3. Добавление строки в таблицу Orders, связывающую строку с идентификатором клиента.
4. Выборка идентификатора нового заказа, присвоенного ему в таблице Orders.
Рекомендуемые материалы
5. Добавление одной строки в таблицу OrderItems для каждого заказанного предмета, соотнесение его с таблицей Orders посредством выбранного идентификатора и с таблицей Products посредством идентификатора продукта.
Теперь предположим, что какая-то ошибка в базе данных, например, нехватка места на диске, ограничения, связанные с безопасностью, блокировка таблицы, помешала завершить эту последовательность действий.
Что в этом случае случится с данными?
Хорошо, если ошибка произойдет после добавления информации о клиенте в таблицу, но до того как она будет добавлена в таблицу Orders – в этом случае проблем не будет, так как можно иметь данные о клиентах без заказов. При повторном выполнении последовательности добавленная запись о клиенте будет возвращена и использована. Можно будет продолжить работу с того места, на котором остановились.
На что будет, если ошибка произойдет после того, как была добавлена строка в таблицу Orders, но до того, как будут добавлены строки в таблицу OrderItems? Теперь в базе данных будет присутствовать пустой заказ.
Еще будет хуже, если система сделает ошибку в процессе добавления строк в таблицу OrderItems? В этом случае в базу данных заказ будет внесен лишь частично, и мы даже не будем знать об этом.
Как решается эта проблема? Необходимо применить транзактную организацию обработки данных, т.е. обработку транзакций.
Обработка транзакций – это механизм, используемый для управления наборами операций SQL, которые должны быть выполнены в пакете, т.е. таким образом, чтобы в базу данных не могли попасть результаты частичного выполнения этого пакета операций. При обработке транзакций можно быть уверенным в том, что выполнение набора операций не было прервано на середине – они были выполнены все, или не была выполнена ни одна из них. Если ошибки не произошло, результаты работы всего набора операторов записываются в таблицах базы данных. Если произошла ошибка, должна быть выполнена отмена всех операций, чтобы возвратить базу данных в известное и безопасное состояние.
Возвращаясь к примеру, процесс должен выполняться так.
1. Проверка, содержится ли информация о клиенте в базе данных. Если нет, такая информация добавляется.
2. Фиксация информации о клиенте.
3. Выборка идентификатора клиента.
4. Добавление строки в таблицу Orders, связывающую строку с идентификатором клиента.
5. Если во время добавления строки в таблицу Orders происходит ошибка, операция отменяется.
6. Выборка идентификатора нового заказа, присвоенного ему в таблице Orders.
7. Добавление одной строки в таблицу OrderItems для каждого заказанного предмета, соотнесение его с таблицей Orders посредством выбранного идентификатора и с таблицей Products посредством идентификатора продукта.
8. Если в процессе добавления строк в таблицу OrderItems происходит ошибка, добавление всех строк в таблицу OrderItems отменяется.
При работе с транзакциями определяются термины:
· Транзакция (Transaction). Блок операторов SQL.
· Отмена (Rollback). Процесс аннулирования указанных операторов SQL. (Другое название — откат).
· Фиксация (Commit). Запись несохраненных операторов SQL в таблицы базы данных.
· Точка сохранения (Savepoint). Временное состояние в ходе выполнения транзакции, в которое можно вернуться после отмены части операций пакета, в отличие от отмены всей транзакции. Иногда это состояние называют «точка отката».
Обработка транзакций используется в ходе управления действием операторов INSERT, UPDATE и DELETE, а также CREATE, DROP. Нет смысла отменять действие оператора SELECT.
20.2. Управляемые транзакции
Точный синтаксис, используемый для обработки транзакций, для разных СУБД различен.
Чтобы сделать транзакцию управляемой, нужно разбить ее SQL-операторы на логические части и явно указать, когда может быть выполнена отмена, а когда нет.
В некоторых СУБД требуется, чтобы явно отметили начало и конец каждого блока операторов транзакции. Например, в SQL Server нужно сделать следующее:
BEGIN TRANSACTION
. . .
COMMIT TRANSACTION
Все операторы, заключенные между BEGIN TRANSACTION и COMMIT TRANSACTION, должны быть выполнены, или не выполнены.
В СУБД MySQL это выглядит так:
START TRANSACTION
. . .
20.3. Использование оператора ROLLBACK
Оператор ROLLBACK используется для отмены операторов SQL. Это записывается так:
DELETE FROM Orders;
ROLLBACK;
В примере выполняется и сразу же, посредством оператора ROLLBACK, аннулируется операция DELETE. Это не самый полезный пример, он показывает, что будучи включенными в блок транзакции, операции DELETE (INSERT и UPDATE) не являются окончательными.
20.4. Использование оператора COMMIT
Обычно после выполнения операторов SQL результаты записываются непосредственно в таблицы баз данных. Это называется неявная фиксация – операция фиксации (сохранения или записи) выполняется автоматически.
Однако внутри блока транзакции фиксация неявно может и не проводиться. Это зависит от того, с какой СУБД вы работаете. Некоторые СУБД трактуют завершение транзакции как неявную фиксацию.
Для безусловного выполнения неявной фиксации используется оператор COMMIT. Пример для SQL Server:
BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION
В примере заказ номер 12345 полностью удаляется из системы. Поскольку это приводит к обновлению двух таблиц базы данных, Orders и OrderItems, блок транзакции применяется для того, чтобы заказ не мог быть удален лишь частично. Конечный оператор COMMIT записывает изменения только в случае, если не произошло ошибки. Если первый оператор будет выполнен, а второй, из=за ошибки, не выполнен, удаление не будет зафиксировано.
Чтобы выполнить то же самое в СУБД Oracle, нужно сделать следующее:
DELETE OrderItems WHERE order_num = 12345;
DELETE Orders WHERE order_num = 12345;
COMMIT;
20.5. Использование точек сохранения
Простые операторы ROLLBACK и COMMIT позволяют записывать или отменять транзакции в целом. Хотя это вполне применимо по отношению к простым транзакциям, для более сложных могут понадобиться частичные фиксации или отмены.
Например, процесс добавления заказа, описанный выше, представляет собой одну транзакцию. Если произойдет ошибка, база данных вернется в состояние, когда строка в таблицу Orders еще не была добавлена. Но вряд ли нужно отменить добавление данных в таблицу Customers, если оно было сделано.
Для отмены части транзакции необходимо иметь возможность размещение метое в важных точках блока транзакции. Потом, если понадобится отмена, можно вернуть базу данных в состояние, соответствующее одной из меток.
В языке SQL эти метки называются точками сохранения (savepoints). Для создания такой точки в СУБД MySQL и Oracle применяется оператор SAVEPOINT:
SAVEPOINT deletel;
В SQL Server это будет так:
Лекция 11 — Разработка системы адаптивного управления — лекция, которая пользуется популярностью у тех, кто читал эту лекцию.
SAVE TRANSACTION deletel;
Каждая точка сохранения должна иметь уникальное имя, идентифицирующее ее таким образом, чтобы, когда выполняется отмена, СУБД знала, в какую точку она должна вернуться. Чтобы выполнить отмену действия всех операторов после этой точки, в СУБД SQL Server нужно выполнить:
ROLLBACK TRANSACTIOM delete;
В MySQL и Oracle это так:
ROLLBACK TO delete;
Чем больше точек сохранения, тем лучше.
Обработка транзакций — это обработка информации в информатике, которая разделена на отдельные неделимые операции, называемые транзакциями. Каждая транзакция должна быть успешной или терпеть неудачу как единое целое; он никогда не может быть завершен только частично.
Например, когда вы покупаете книгу в книжном онлайн-магазине, вы обмениваете деньги (в виде кредита) на книгу. Если у вас хороший кредит, ряд связанных операций гарантирует, что вы получите книгу, а книжный магазин — ваши деньги. Однако, если во время обмена происходит сбой одной операции в серии, происходит сбой всего обмена. Вы не получаете книгу, а книжный магазин не получает ваши деньги. Технология, обеспечивающая сбалансированность и предсказуемость обмена, называется обработкой транзакций. Транзакции гарантируют, что ресурсы, ориентированные на данные, не будут постоянно обновляться, если все операции в транзакционной единице не завершатся успешно. Объединив набор связанных операций в единицу, которая либо полностью завершается успешно, либо полностью выходит из строя, можно упростить восстановление после ошибок и сделать свое приложение более надежным.
Системы обработки транзакций состоят из компьютерного оборудования и программного обеспечения, содержащего ориентированное на транзакцию приложение, которое выполняет рутинные транзакции, необходимые для ведения бизнеса. Примеры включают системы, которые управляют вводом заказов на продажу, бронированием авиакомпаний, расчетом заработной платы, записями сотрудников, производством и отгрузкой.
Поскольку большая часть, но не обязательно все, обработка транзакций сегодня является интерактивной, этот термин часто рассматривается как синоним онлайн-обработки транзакций.
Содержание
- 1 Описание
- 2 Методология
- 2.1 Откат
- 2.2 Откат
- 2.3 Тупики
- 2.4 Компенсация транзакции
- 3 Критерии ACID
- 3.1 Атомарность
- 3.2 Согласованность
- 3.3 Изоляция
- 3.4 Долговечность
- 4 Преимущества
- 5 Недостатки
- 6 Реализации
- 7 Ссылки
- 8 Дополнительная литература
- 9 Внешние ссылки
Описание
Обработка транзакций предназначена для поддержания целостности системы (обычно база данных или некоторые современные файловые системы ) в известном согласованном состоянии, гарантируя, что все взаимозависимые операции в системе либо завершены успешно, либо все успешно отменены.
Например, рассмотрим типичную банковскую транзакцию, которая включает перевод 700 долларов со сберегательного счета клиента на текущий счет клиента. Эта транзакция включает по крайней мере две отдельные операции с компьютерной точки зрения: списание сберегательного счета на 700 долларов и кредитование текущего счета на 700 долларов. Если одна операция завершится успешно, а другая — нет, счета банка не будут сбалансированы в конце дня. Следовательно, должен быть способ гарантировать, что либо обе операции будут успешными, либо обе будут неудачными, чтобы в базе данных банка в целом никогда не было несоответствий.
Обработка транзакций связывает несколько отдельных операций в одну неделимую транзакцию и гарантирует, что либо все операции в транзакции завершены без ошибок, либо ни одна из них не завершится. Если некоторые операции завершены, но при попытке выполнения других возникают ошибки, система обработки транзакций «откатывает» все операции транзакции (включая успешные), тем самым стирая все следы транзакции и восстанавливая систему. в согласованное известное состояние, в котором он находился до начала обработки транзакции. Если все операции транзакции завершены успешно, транзакция фиксируется системой, и все изменения в базе данных становятся постоянными; после этого транзакцию нельзя будет откатить.
Обработка транзакций защищает от аппаратных и программных ошибок, которые могут привести к частичному завершению транзакции. Если компьютерная система выходит из строя в середине транзакции, система обработки транзакций гарантирует, что все операции в любых незавершенных транзакциях будут отменены.
Как правило, транзакции проводятся одновременно. Если они перекрываются (т. Е. Должны касаться одной и той же части базы данных), это может вызвать конфликты. Например, если клиент, упомянутый в приведенном выше примере, имеет 150 долларов на своем сберегательном счете и пытается перевести 100 долларов другому лицу, одновременно переводя 100 долларов на текущий счет, только один из них может добиться успеха. Однако принудительная обработка транзакций последовательно неэффективна. Следовательно, параллельные реализации обработки транзакций запрограммированы таким образом, чтобы гарантировать, что конечный результат будет отражать бесконфликтный результат, такой же, какой мог бы быть достигнут при последовательном выполнении транзакций в любом порядке (свойство, называемое сериализуемость ). В нашем примере это означает, что независимо от того, какая транзакция была запущена первой, перевод другому лицу или переход на текущий счет будет успешным, а другой — неудачным.
Методология
Основные принципы всех систем обработки транзакций одинаковы. Однако терминология может отличаться от одной системы обработки транзакций к другой, и используемые ниже термины не обязательно универсальны.
Откат
Системы обработки транзакций обеспечивают целостность базы данных, записывая промежуточные состояния базы данных по мере ее изменения, а затем используя эти записи для восстановления базы данных до известного состояния, если транзакция не может быть зафиксирована. Например, копии информации в базе данных до ее модификации транзакцией откладываются системой до того, как транзакция сможет внести какие-либо изменения (это иногда называется предыдущим изображением). Если какая-либо часть транзакции терпит неудачу до ее фиксации, эти копии используются для восстановления базы данных до состояния, в котором она была до начала транзакции.
Повтор транзакций
Также можно вести отдельный журнал всех изменений в системе управления базами данных. (иногда называют после изображений). Это не требуется для отката неудачных транзакций, но полезно для обновления системы управления базой данных в случае сбоя базы данных, поэтому некоторые системы обработки транзакций предоставляют это. Если система управления базой данных полностью выйдет из строя, ее необходимо восстановить из самой последней резервной копии. Резервная копия не будет отражать транзакции, совершенные с момента создания резервной копии. Однако после восстановления системы управления базой данных журнал остаточных образов может быть применен к базе данных (повтор транзакций), чтобы обновить систему управления базой данных. После этого можно будет выполнить откат любых транзакций, выполнявшихся на момент сбоя. Результатом является база данных в согласованном известном состоянии, которое включает результаты всех транзакций, зафиксированных до момента сбоя.
Тупиковые ситуации
В некоторых случаях две транзакции могут в процессе своей обработки попытаться получить доступ к одной и той же части базы данных одновременно таким образом, чтобы они не могли продолжить. Например, транзакция A может получить доступ к части X базы данных, а транзакция B может получить доступ к части Y базы данных. Если в этот момент транзакция A пытается получить доступ к части Y базы данных, в то время как транзакция B пытается получить доступ к части X, возникает тупик, и ни одна из транзакций не может двигаться вперед. Системы обработки транзакций предназначены для обнаружения этих тупиковых ситуаций, когда они возникают. Обычно обе транзакции отменяются и откатываются, а затем они запускаются снова в другом порядке, автоматически, чтобы взаимоблокировка больше не возникала. Или иногда только одна из заблокированных транзакций отменяется, откатывается и автоматически перезапускается после небольшой задержки.
Тупиковые ситуации также могут возникать между тремя и более транзакциями. Чем больше транзакций задействовано, тем сложнее их обнаружить, до такой степени, что системы обработки транзакций обнаруживают, что существует практический предел тупиковых ситуаций, которые они могут обнаружить.
Компенсационная транзакция
В системах, где механизмы фиксации и отката недоступны или нежелательны, компенсирующая транзакция часто используется для отмены неудачных транзакций и восстановления системы до предыдущего штат.
Критерии ACID
Джим Грей в конце 1970-х определяли свойства надежной транзакционной системы под аббревиатурой ACID — атомарность, согласованность, изоляция и долговечность.
Атомарность
Изменения состояния транзакции являются атомарными: либо все происходит, либо ничего не происходит. Эти изменения включают изменения базы данных, сообщения и действия с датчиками.
Согласованность
Согласованность : транзакция — это правильное преобразование состояния. Действия, предпринятые как группа, не нарушают никаких ограничений целостности, связанных с состоянием.
Изоляция
Несмотря на то, что транзакции выполняются одновременно, каждой транзакции T кажется, что другие выполнялись либо до T, либо после T, но не одновременно.
Долговечность
После успешного завершения (фиксации) транзакции ее изменения в базе данных сохраняются после сбоев и сохраняют свои изменения.
Преимущества
Обработка транзакций имеет следующие преимущества:
- Она позволяет разделять компьютерные ресурсы между многими пользователями
- Она сдвигает время обработки задания на то, когда вычислительные ресурсы Менее загружен
- Это позволяет избежать простоя вычислительных ресурсов без поминутного вмешательства человека и наблюдения.
- Он используется на дорогих классах компьютеров, чтобы помочь окупить стоимость за счет сохранения высокой степени использования эти дорогие ресурсы
Недостатки
- У них относительно высокая стоимость установки
- Отсутствие стандартных форматов
- Несовместимость аппаратного и программного обеспечения
Реализации
Стандарт программное обеспечение для обработки транзакций , такое как IBM Information Management System, было впервые разработано в 1960-х годах и часто было тесно связано с конкретной базой данных системы управления. В клиент-серверных вычислениях аналогичные принципы реализовывались в 1980-х годах с переменным успехом. Однако в последние годы поддерживать модель распределенного клиент-сервер значительно сложнее. Поскольку количество транзакций росло в ответ на различные онлайн-сервисы (особенно Web ), единая распределенная база данных не была практическим решением. Кроме того, большинство онлайн-систем состоят из целого набора программ, работающих вместе, в отличие от строгой модели клиент-сервер, в которой один сервер может обрабатывать транзакции. Сегодня доступен ряд систем обработки транзакций, которые работают на межпрограммном уровне и масштабируются до больших систем, включая мэйнфреймы.
. Одно усилие — X / Open Distributed Transaction Processing (DTP) (см. также Java Transaction API (JTA). Однако проприетарные среды обработки транзакций, такие как IBM CICS, по-прежнему очень популярны, хотя CICS эволюционировала и теперь включает открытые отраслевые стандарты..
Термин экстремальная обработка транзакций (XTP) использовался для описания систем обработки транзакций с необычно сложными требованиями, в частности требованиями к пропускной способности (количество транзакций в секунду). Такие системы могут быть реализованы с помощью распределенной архитектуры или архитектуры кластерного типа. используется по крайней мере до 2011 года.
Ссылки
Дополнительная литература
- Герхард Вейкум, Готфрид Фоссен, Транзакционные информационные системы: теория, алгоритмы и практика управления параллельным выполнением и восстановления, Морган Кауфманн, 2002, ISBN 1-55860-508-8
- Джим Грей, Андреас Рейтер, Обработка транзакций — концепции и методы, 1993, Морган Кауфманн, ISBN 1-55860-190-2
- Филип А. Бернштейн, Эрик Ньюкомер, Принципы обработки транзакций, 1997, Морган Кауфманн, ISBN 1-55860-415- 4
- Ахмед К. Эльмагармид (редактор), Модели транзакций для расширенных приложений баз данных, Морган-Кауфманн, 1992, ISBN 1-55860-214-3
Внешние ссылки
![]() |
На Викискладе есть материалы, посвященные обработке транзакций. |
Приветствую всех посетителей сайта Info-Comp.ru! В этом материале мы с Вами подробно рассмотрим транзакции языка T-SQL, Вы узнаете, что это такое, для чего они нужны, а также какие команды управления транзакциями существуют в T-SQL.
Заметка! T-SQL – это расширение языка SQL, реализованное в Microsoft SQL Server. Более подробно об этом можете почитать в статье – Что такое T-SQL. Подробное описание для начинающих.
Содержание
- Транзакции в T-SQL
- Свойства транзакции
- Команды управления транзакциями в T-SQL
- Примеры транзакций в T-SQL
- Исходные данные для примеров
- Простой пример транзакции в T-SQL
- Пример транзакции в T-SQL с обработкой ошибок
- Уровни изоляции транзакций в T-SQL
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
- SNAPSHOT и READ COMMITTED SNAPSHOT
- Побочные эффекты параллелизма
- Включение уровня изоляции в T-SQL
Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе, или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены. Другими словами, если одна команда или инструкция внутри транзакции завершилась с ошибкой, то все, что было отработано перед ней, также отменяется, даже если предыдущие команды завершились успешно.
Транзакции очень полезны и просто незаменимы в тех случаях, когда Вам необходимо реализовывать бизнес логику в базе данных Microsoft SQL Server, которая предполагает многошаговые операции, где каждый шаг логически связан с другими шагами.
По сути каждая отдельная инструкция языка T-SQL является транзакцией, это называется «Автоматическое принятие транзакций» или «Неявные транзакции», но также есть и явные транзакции, это когда мы сами явно начинаем транзакцию и также явно заканчиваем ее, т.е. делаем все это с помощью специальных команд.
Чтобы понять, как работают транзакции и для чего они нужны, давайте рассмотрим классический пример, который наглядно показывает необходимость использования транзакций.
Допустим, у Вас есть хранимая процедура, которая осуществляет перевод средств с одного счета на другой, соответственно, как минимум у Вас будет две операции в этой процедуре, снятие средств, и зачисление средств, например, две инструкции UPDATE.
Заметка! Назначение хранимых процедур в языке T-SQL.
Но в каждой из этих операций может возникнуть ошибка и инструкция не выполнится. А теперь представьте, что первая инструкция снимает деньги, она выполнилась успешно, вторая инструкция зачисляет деньги и в ней возникла ошибка, без транзакции снятые деньги просто потеряются, так как они никуда не будут зачислены.
Чтобы этого не допустить, все SQL инструкции, которые логически что-то объединяет, в данном случае все операции, связанные с переводом средств, пишут внутри транзакции, и тогда, если наступит подобная ситуация, все изменения будут отменены, т.е. деньги вернутся обратно на счет.
Транзакции можно сочетать с обработкой и перехватом ошибок TRY…CATCH, иными словами, Вы отслеживаете ошибки в Вашем блоке инструкций и если они появляются, то в блоке CATCH Вы откатываете транзакцию, т.е. отменяете все изменения, которые были успешно выполнены до возникновения ошибки в транзакции.
Транзакции – это отличный механизм обеспечения целостности данных.
Свойства транзакции
У транзакции есть 4 очень важных свойства:
- Атомарность – все команды в транзакции либо полностью выполняются, и соответственно, фиксируются все изменения данных, либо ничего не выполняется и ничего не фиксируется;
- Согласованность – данные, в случае успешного выполнения транзакции, должны соблюдать все установленные правила в части различных ограничений, первичных и внешних ключей, определенных в базе данных;
- Изоляция – механизм предоставления доступа к данным. Транзакция изолирует данные, с которыми она работает, для того чтобы другие транзакции получали только согласованные данные;
- Надежность – все внесенные изменения фиксируются в журнале транзакций и данные считаются надежными, если транзакция была успешно завершена. В случае сбоя SQL Server сверяет данные, записанные в базе данных, с журналом транзакций, если есть успешно завершенные транзакции, которые не закончили процесс записи всех изменений в базу данных, они будут выполнены повторно. Все действия, выполненные не подтвержденными транзакциями, отменяются.
Заметка! Чем отличаются функции от хранимых процедур в T-SQL.
Команды управления транзакциями в T-SQL
В T-SQL для управления транзакциями существуют следующие основные команды:
- BEGIN TRANSACTION (можно использовать сокращённую запись BEGIN TRAN) – команда служит для определения начала транзакции. В качестве параметра этой команде можно передать и название транзакции, полезно, если у Вас есть вложенные транзакции;
- COMMIT TRANSACTION (можно использовать сокращённую запись COMMIT TRAN) – с помощью данной команды мы сообщаем SQL серверу об успешном завершении транзакции, и о том, что все изменения, которые были выполнены, необходимо сохранить на постоянной основе;
- ROLLBACK TRANSACTION (можно использовать сокращённую запись ROLLBACK TRAN) – служит для отмены всех изменений, которые были внесены в процессе выполнения транзакции, например, в случае ошибки, мы откатываем все назад;
- SAVE TRANSACTION (можно использовать сокращённую запись SAVE TRAN) – данная команда устанавливает промежуточную точку сохранения внутри транзакции, к которой можно откатиться, в случае возникновения необходимости.
Примеры транзакций в T-SQL
Давайте рассмотрим примеры транзакций, реализованные на языке T-SQL.
Исходные данные для примеров
Но сначала нам необходимо создать тестовые данные для нашего примера.
Для этого выполните следующую инструкцию.
--Создание таблицы CREATE TABLE Goods ( ProductId INT IDENTITY(1,1) NOT NULL, ProductName VARCHAR(100) NOT NULL, Price MONEY NULL, ); --Добавление данных в таблицу INSERT INTO Goods(ProductName, Price) VALUES ('Системный блок', 50), ('Клавиатура', 30), ('Монитор', 100); SELECT ProductId, ProductName, Price FROM Goods;
Приветствую всех посетителей сайта Info-Comp.ru! В этом материале мы с Вами подробно рассмотрим транзакции языка T-SQL, Вы узнаете, что это такое, для чего они нужны, а также какие команды управления транзакциями существуют в T-SQL.
Заметка! T-SQL – это расширение языка SQL, реализованное в Microsoft SQL Server. Более подробно об этом можете почитать в статье – Что такое T-SQL. Подробное описание для начинающих.
Содержание
- Транзакции в T-SQL
- Свойства транзакции
- Команды управления транзакциями в T-SQL
- Примеры транзакций в T-SQL
- Исходные данные для примеров
- Простой пример транзакции в T-SQL
- Пример транзакции в T-SQL с обработкой ошибок
- Уровни изоляции транзакций в T-SQL
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
- SNAPSHOT и READ COMMITTED SNAPSHOT
- Побочные эффекты параллелизма
- Включение уровня изоляции в T-SQL
Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе, или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены. Другими словами, если одна команда или инструкция внутри транзакции завершилась с ошибкой, то все, что было отработано перед ней, также отменяется, даже если предыдущие команды завершились успешно.
Транзакции очень полезны и просто незаменимы в тех случаях, когда Вам необходимо реализовывать бизнес логику в базе данных Microsoft SQL Server, которая предполагает многошаговые операции, где каждый шаг логически связан с другими шагами.
По сути каждая отдельная инструкция языка T-SQL является транзакцией, это называется «Автоматическое принятие транзакций» или «Неявные транзакции», но также есть и явные транзакции, это когда мы сами явно начинаем транзакцию и также явно заканчиваем ее, т.е. делаем все это с помощью специальных команд.
Чтобы понять, как работают транзакции и для чего они нужны, давайте рассмотрим классический пример, который наглядно показывает необходимость использования транзакций.
Допустим, у Вас есть хранимая процедура, которая осуществляет перевод средств с одного счета на другой, соответственно, как минимум у Вас будет две операции в этой процедуре, снятие средств, и зачисление средств, например, две инструкции UPDATE.
Заметка! Назначение хранимых процедур в языке T-SQL.
Но в каждой из этих операций может возникнуть ошибка и инструкция не выполнится. А теперь представьте, что первая инструкция снимает деньги, она выполнилась успешно, вторая инструкция зачисляет деньги и в ней возникла ошибка, без транзакции снятые деньги просто потеряются, так как они никуда не будут зачислены.
Чтобы этого не допустить, все SQL инструкции, которые логически что-то объединяет, в данном случае все операции, связанные с переводом средств, пишут внутри транзакции, и тогда, если наступит подобная ситуация, все изменения будут отменены, т.е. деньги вернутся обратно на счет.
Транзакции можно сочетать с обработкой и перехватом ошибок TRY…CATCH, иными словами, Вы отслеживаете ошибки в Вашем блоке инструкций и если они появляются, то в блоке CATCH Вы откатываете транзакцию, т.е. отменяете все изменения, которые были успешно выполнены до возникновения ошибки в транзакции.
Транзакции – это отличный механизм обеспечения целостности данных.
Свойства транзакции
У транзакции есть 4 очень важных свойства:
- Атомарность – все команды в транзакции либо полностью выполняются, и соответственно, фиксируются все изменения данных, либо ничего не выполняется и ничего не фиксируется;
- Согласованность – данные, в случае успешного выполнения транзакции, должны соблюдать все установленные правила в части различных ограничений, первичных и внешних ключей, определенных в базе данных;
- Изоляция – механизм предоставления доступа к данным. Транзакция изолирует данные, с которыми она работает, для того чтобы другие транзакции получали только согласованные данные;
- Надежность – все внесенные изменения фиксируются в журнале транзакций и данные считаются надежными, если транзакция была успешно завершена. В случае сбоя SQL Server сверяет данные, записанные в базе данных, с журналом транзакций, если есть успешно завершенные транзакции, которые не закончили процесс записи всех изменений в базу данных, они будут выполнены повторно. Все действия, выполненные не подтвержденными транзакциями, отменяются.
Заметка! Чем отличаются функции от хранимых процедур в T-SQL.
Команды управления транзакциями в T-SQL
В T-SQL для управления транзакциями существуют следующие основные команды:
- BEGIN TRANSACTION (можно использовать сокращённую запись BEGIN TRAN) – команда служит для определения начала транзакции. В качестве параметра этой команде можно передать и название транзакции, полезно, если у Вас есть вложенные транзакции;
- COMMIT TRANSACTION (можно использовать сокращённую запись COMMIT TRAN) – с помощью данной команды мы сообщаем SQL серверу об успешном завершении транзакции, и о том, что все изменения, которые были выполнены, необходимо сохранить на постоянной основе;
- ROLLBACK TRANSACTION (можно использовать сокращённую запись ROLLBACK TRAN) – служит для отмены всех изменений, которые были внесены в процессе выполнения транзакции, например, в случае ошибки, мы откатываем все назад;
- SAVE TRANSACTION (можно использовать сокращённую запись SAVE TRAN) – данная команда устанавливает промежуточную точку сохранения внутри транзакции, к которой можно откатиться, в случае возникновения необходимости.
Примеры транзакций в T-SQL
Давайте рассмотрим примеры транзакций, реализованные на языке T-SQL.
Исходные данные для примеров
Но сначала нам необходимо создать тестовые данные для нашего примера.
Для этого выполните следующую инструкцию.
--Создание таблицы CREATE TABLE Goods ( ProductId INT IDENTITY(1,1) NOT NULL, ProductName VARCHAR(100) NOT NULL, Price MONEY NULL, ); --Добавление данных в таблицу INSERT INTO Goods(ProductName, Price) VALUES ('Системный блок', 50), ('Клавиатура', 30), ('Монитор', 100); SELECT ProductId, ProductName, Price FROM Goods;
Заметка! Создание таблиц в Microsoft SQL Server (CREATE TABLE) – подробная инструкция.
Простой пример транзакции в T-SQL
В данном примере у нас всего две инструкции, которые изменяют данные, но допустим, что они взаимосвязаны, т.е. они обе обязательно должны выполниться вместе или не выполниться также вместе.
Поэтому мы решили эти инструкции объединить в одну транзакцию.
Сначала мы открываем транзакцию командой BEGIN TRANSACTION, далее пишем все необходимые инструкции, которые мы хотим объединить в транзакцию.
После этого командой COMMIT TRANSACTION мы сохраняем все внесенные изменения.
В данном случае у нас нет никаких ошибок, все инструкции выполнились успешно. Как результат, транзакция завершена также успешно и все изменения сохранены на постоянной основе командой COMMIT TRANSACTION.
BEGIN TRANSACTION --Инструкция 1 UPDATE Goods SET Price = 70 WHERE ProductId = 1; --Инструкция 2 UPDATE Goods SET Price = 40 WHERE ProductId = 2; COMMIT TRANSACTION SELECT ProductId, ProductName, Price FROM Goods;
Однако, если в любой из инструкций возникнет ошибка, транзакция не завершится, и все изменения не сохранятся.
При этом, стоит помнить о том, что ошибки с определённым уровнем серьезности, например, ошибки, связанные с нарушением ограничений, не влекут за собой автоматический откат всех изменений внесенных текущей транзакцией, поэтому всегда необходимо использовать или инструкцию SET XACT_ABORT ON, или обработку ошибок (допускается и совместное использование).
Например, если во второй инструкции мы попытаемся записать в столбец Price какое-нибудь текстовое значение, то у нас возникнет ошибка, и изменения, внесённые первой инструкцией, не зафиксируются на постоянной основе.
Пример транзакции в T-SQL с обработкой ошибок
В языке T-SQL существует механизм перехвата и обработки ошибок – конструкция TRY… CATCH.
Эту конструкцию можно использовать для отслеживания появления возможных ошибок внутри транзакции и в случае появления таких ошибок предпринять определенные действия.
Сначала мы открываем блок для обработки ошибок, затем открываем транзакцию командой BEGIN TRANSACTION, далее пишем наши инструкции, например, те же самые две инструкции UPDATE.
После этого закрываем блок TRY, открываем блок CATCH, в котором в случае возникновения ошибки мы откатываем все изменения командой ROLLBACK TRANSACTION. Также мы принудительно завершаем нашу инструкцию командой RETURN.
Если ошибок нет, то в блок CATCH мы, соответственно, не попадаем и у нас выполнится команда COMMIT TRANSACTION, которая сохранит все изменения.
В этом примере нет ошибок, поэтому транзакция завершена успешно.
Заметка! Обработка ошибок в языке T-SQL – конструкция TRY CATCH.
BEGIN TRY --Начало транзакции BEGIN TRANSACTION --Инструкция 1 UPDATE Goods SET Price = 70 WHERE ProductId = 1; --Инструкция 2 UPDATE Goods SET Price = 40 WHERE ProductId = 2; END TRY BEGIN CATCH --В случае непредвиденной ошибки --Откат транзакции ROLLBACK TRANSACTION --Выводим сообщение об ошибке SELECT ERROR_NUMBER() AS [Номер ошибки], ERROR_MESSAGE() AS [Описание ошибки] --Прекращаем выполнение инструкции RETURN END CATCH --Если все хорошо. Сохраняем все изменения COMMIT TRANSACTION GO SELECT ProductId, ProductName, Price FROM Goods;
А в этом примере мы намерено допускаем ошибку во второй инструкции. Поэтому управление передается в блок CATCH, где мы откатываем все изменения, возвращаем номер и описание ошибки и принудительно завершаем всю инструкцию командой RETURN.
Первая инструкция отработала нормально, но ее изменения не были сохранены, так как вторая инструкция выполнена с ошибкой.
Заметка! Чем отличается инструкция THROW от RAISERROR в T-SQL.
Уровни изоляции транзакций в T-SQL
Во время выполнения транзакции все данные, над которыми производятся изменения, блокируются, до завершения транзакции, так как, когда один процесс изменяет данные, другой процесс не может одновременно изменять их. В SQL сервере существует механизм, который блокирует (изолирует) данные во время выполнения транзакции. У данного механизма есть несколько уровней изоляции, каждый из которых определяет степень блокировки данных.
Давайте подробней рассмотрим уровни изоляции.
READ UNCOMMITTED
Самый низкий уровень, при котором SQL сервер разрешает так называемое «грязное чтение». Грязным чтением называют считывание неподтвержденных данных, иными словами, если транзакция, которая изменяет данные, не завершена, другая транзакция может получить уже измененные данные, хотя они еще не зафиксированы и могут отмениться.
READ COMMITTED
Этот уровень уже запрещает грязное чтение, в данном случае все процессы, запросившие данные, которые изменяются в тот же момент в другой транзакции, будут ждать завершения этой транзакции и подтверждения фиксации данных. Данный уровень по умолчанию используется SQL сервером.
REPEATABLE READ
На данном уровне изоляции запрещается изменение данных между двумя операциями чтения в одной транзакции. Здесь происходит запрет на так называемое «неповторяющееся чтение» или «несогласованный анализ». Другими словами, если в одной транзакции есть несколько операций чтения, данные будут блокированы и их нельзя будет изменить в другой транзакции. Таким образом, Вы избежите ситуации, когда вначале транзакции Вы запросили данные, провели их анализ (некое вычисление), в конце транзакции запросили те же самые данные, а они уже отличаются от первоначальных, так как они были изменены другой транзакцией.
Также уровень REPEATABLE READ, как и остальные, запрещает «Потерянное обновление» – это когда две транзакции сначала считывают одни и те же данные, а затем изменяют их на основе неких вычислений, в результате обе транзакции выполнятся, но данные будут те, которая зафиксировала последняя операция обновления. Это происходит потому, что данные в операциях чтения в начале этих транзакций не были заблокированы.
SERIALIZABLE
Данный уровень исключает чтение «фантомных» записей. Фантомные записи – это те записи, которые появились между началом и завершением транзакции. Иными словами, в начале транзакции Вы запросили определенные данные, в конце транзакции Вы запрашиваете их снова с тем же фильтром, но там уже есть и новые данные, которые добавлены другой транзакцией. Более низкие уровни изоляции не блокировали строки, которых еще нет в таблице, данный уровень блокирует все строки, соответствующие фильтру запроса, с которыми будет работать транзакция, как существующие, так и те, что могут быть добавлены.
SNAPSHOT и READ COMMITTED SNAPSHOT
Также существуют уровни изоляции, алгоритм которых основан на версиях строк, это
- SNAPSHOT
- READ COMMITTED SNAPSHOT
Иными словами, SQL Server делает снимок и хранит последние версии подтвержденных строк. В данном случае, клиенту не нужно ждать снятия блокировок, пока одна транзакция изменит данные, он сразу получает последнюю версию подтвержденных строк. Следует отметить, что уровни изоляции, основанные на версиях строк, замедляют операции обновления и удаления, так как перед этими операциями сервер делает и копирует снимок строк во временную базу данных.
SNAPSHOT – уровень хранит строки, подтверждённые на момент начала транзакции, соответственно, именно эти строки будут считаны в случае обращения к ним из другой транзакции. Данный уровень исключает повторяющееся и фантомное чтение примерно так же, как уровень SERIALIZABLE.
READ COMMITTED SNAPSHOT – этот уровень изоляции работает практически так же, как уровень SNAPSHOT, с одним отличием, он хранит снимок строк, которые подтверждены на момент запуска команды, а не транзакции, как в SNAPSHOT.
Заметка! Обзор Azure Data Studio. Что это за инструмент и для чего он нужен.
Побочные эффекты параллелизма
На основе вышеизложенного мы можем выделить несколько побочных эффектов, которые могут возникнуть в результате параллельного использования данных:
- Потерянное обновление (Lost Update) – при одновременном изменении данных разными транзакциями одно из изменений будет потеряно;
- Грязное чтение (Dirty Read) – чтение неподтвержденных данных;
- Неповторяющееся чтение (Non-Repeatable Read) – чтение измененных данных в рамках одной транзакции;
- Фантомное чтение (Phantom Reads) – чтение записей, которые появились между началом и завершением транзакции.
Каждый из уровней изоляции устраняет определенные побочные эффекты. В таблице ниже приведены сводные данные.
Побочный эффект / Уровень изоляции | Потерянное обновление | Грязное чтение | Неповторяющееся чтение | Фантомные записи |
READ UNCOMMITTED | Устраняет | Не устраняет | Не устраняет | Не устраняет |
READ COMMITTED | Устраняет | Устраняет | Не устраняет | Не устраняет |
REPEATABLE READ | Устраняет | Устраняет | Устраняет | Не устраняет |
SERIALIZABLE | Устраняет | Устраняет | Устраняет | Устраняет |
SNAPSHOT | Устраняет | Устраняет | Устраняет | Устраняет |
READ COMMITTED SNAPSHOT | Устраняет | Устраняет | Устраняет | Устраняет |
Включение уровня изоляции в T-SQL
Для того чтобы включить тот или иной уровень изоляции для всей сессии, необходимо выполнить команду SET TRANSACTION ISOLATION LEVEL и указать название уровня изоляции.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Также для уровней SNAPSHOT и READ COMMITTED SNAPSHOT предварительно необходимо включить параметр базы данных ALLOW_SNAPSHOT_ISOLATION для уровня изоляции SNAPSHOT и READ_COMMITTED_SNAPSHOT для уровня READ COMMITTED SNAPSHOT.
Например
ALTER DATABASE TestDB SET ALLOW_SNAPSHOT_ISOLATION ON;
Заметка! Если Вас интересует язык SQL, то рекомендую почитать книгу «SQL код» – это самоучитель по языку SQL для начинающих программистов. В ней язык SQL рассматривается как стандарт, чтобы после прочтения данной книги можно было работать с языком SQL в любой системе управления базами данных.
На сегодня это все, надеюсь, материал был Вам полезен, до новых встреч!
Oracle поддерживает очень мощную и надежную модель транзакций. Код приложения определяет логическую последовательность выполняемых операций, результаты которой должны быть либо сохранены командой
COMMIT
, либо отменены командой ROLLBACK.
Транзакция начинается неявно с первой команды SQL
, выполняемой после команды COMMIT
или ROLLBACK
(или с начала сеанса) или же после команды ROLLBACK TO SAVEPOINT
. Для управления транзакциями PL/SQL
предоставляет набор команд:
COMMIT
— сохраняет (фиксирует) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK
— отменяет (откатывает) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK TO SAVEPOINT
— отменяет все изменения со времени установки последней точки сохранения и снимает все блокировки, установленные в этой части кода.- SAVEPOINT — устанавливает точку сохранения, после чего становится возможным частичный откат транзакции.
SET TRANSACTION
— позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката.LOCK TABLE
— позволяет заблокировать всю таблицу в указанном режиме. (По умолчанию к таблице обычно применяется блокировка на уровне строк.)
Эти команды более подробно рассматриваются в следующих разделах блога.
Команда COMMIT
Фиксирует все изменения, внесенные в базу данных в ходе сеанса текущей транзакцией. После выполнения этой команды изменения становятся видимыми для других сеансов или пользователей. Синтаксис этой команды:
COMMIT [WORK] [COMMENT текст];
Ключевое слово WORK
не обязательно — оно только упрощает чтение кода.
Ключевое слово COMMENT
также не является обязательным; оно используется для задания комментария, который будет связан с текущей транзакцией. Текстом комментария должен быть заключенный в одинарные кавычки литерал длиной до 50 символов. Обычно комментарии задаются для распределенных транзакций с целью облегчения их анализа и разрешения сомнительных транзакций в среде с двухфазовой фиксацией. Они хранятся в словаре данных вместе с идентификаторами транзакций.
Обратите внимание: команда COMMIT
снимает все блокировки таблиц, установленные во время текущего сеанса (например, для команды SELECT FOR UPDATE
). Кроме того, она удаляет все точки сохранения, установленные после выполнения последней команды COMMIT
или ROLLBACK
.
После того как изменения будут закреплены, их откат становится невозможным.
Все команды в следующем фрагменте являются допустимыми применениями COMMIT
:
COMMIT;
COMMIT WORK;
COMMIT COMMENT 'maintaining account balance'.
Команда ROLLBACK
Команда ROLLBACK
отменяет (полностью или частично) изменения, внесенные в базу данных в текущей транзакции. Для чего это может потребоваться? Например, для исправления ошибок:
DELETE FROM orders;
«Нет, Нет! Я хотел удалить только те заказы, которые были сделаны до мая 2005 года!» Нет проблем — достаточно выполнить команду ROLLBACK. Что касается программирования приложений, в случае возникновения проблем откат позволяет вернуться к исходному состоянию.
Синтаксис команды ROLLBACK
:
ROLLBACK [WORK] [TO [SAVEPOINT] имя_точки_сохранения];
Существует две основные разновидности ROLLBACK
: без параметров и с секцией TO, указывающей, до какой точки сохранения следует произвести откат. Первая отменяет все изменения, выполненные в ходе текущей транзакции, а вторая отменяет все изменения и снимает все блокировки, установленные после заданной точки сохранения. (О том, как установить в приложении точку сохранения, рассказано в следующем разделе.) Имя точки сохранения представляет собой необъявленный идентификатор Oracle
. Это не может быть литерал (заключенный в кавычки) или имя переменной.
Все команды ROLLBACK
в следующем фрагменте действительны :
ROLLBACK;
ROLLBACK WORK;
ROLLBACK TO begin_cleanup;
При откате до заданной точки сохранения все установленные после нее точки стираются, но данная точка остается. Это означает, что можно возобновить с нее транзакцию и при необходимости снова вернуться к этой же точке сохранения.
Непосредственно перед выполнением команды INSERT
, UPDATE
, MERGE
или DELETE PL/SQL
автоматически устанавливает неявную точку сохранения, и если команда завершается ошибкой, выполняется автоматический откат до этой точки. Если в дальнейшем в ходе выполнения команды DML происходит сбой, выполняется автоматический откат до этой точки. Подобным образом отменяется только последняя команда DML
.
Команда SAVEPOINT
Устанавливает в транзакции именованный маркер, позволяющий в случае необходимости выполнить откат до отмеченной точки сохранения. При таком откате отменяются все изменения и удаляются все блокировки после этой точки, но сохраняются изменения и блокировки, предшествовавшие ей. Синтаксис команды SAVEPOINT
:
SAVEPOINT имя_точки_сохранения;
Здесь имя точки сохранения — необъявленный идентификатор. Он должен соответствовать общим правилам формирования идентификаторов Oracle (до 30 символов, начинается с буквы, состоит из букв, цифр и символов #, $ и _), но объявлять его не нужно (да и невозможно).
Область действия точки сохранения не ограничивается блоком PL/SQL, в котором она установлена. Если в ходе транзакции имя точки сохранения используется повторно, эта точка просто «перемещается» в новую позицию, причем независимо от процедуры, функции или анонимного блока, в котором выполняется команда SAVEPOINT
. Если точка сохранения устанавливается в рекурсивной программе, на самом деле на каждом уровне рекурсии она задается заново, но откат может быть возможен только к одной точке — той, что установлена последней.
Команда SET TRANSACTION
Команда SET TRANSACTION
позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката. Эта команда должна быть первой командой SQL
транзакции и дважды использоваться в ходе одной транзакции не может. У нее имеются четыре разновидности.
-
SET TRANSACTION READ ONLY
— определяет текущую транзакцию доступной «только для чтения». В транзакциях этого типа всем запросам доступны лишь те изменения, которые были зафиксированы до начала транзакции. Они применяются, в частности, в медленно формируемых отчетах со множеством запросов, благодаря чему в них часто используются строго согласованные данные. -
SET TRANSACTION READ WRITE
— определяет текущую транзакцию как операцию чтения и записи данных в таблицу. SET TRANSACTION ISOLATION LEVEL SERIALIZABLE | READ COMMITTED
— определяет способ выполнения транзакции, модифицирующей базу данных. С ее помощью можно задать один из двух уровней изоляции транзакции:SERIALIZABLE
илиREAD COMMITTED
. В первом случае командеDML
, пытающейся модифицировать таблицу, которая уже изменена незафиксированной транзакцией, будет отказано в этой операции. Для выполнения этой команды в инициализационном параметре COMPATIBLE базы данных должна быть задана версия 7.3.0 и выше.При установке уровняREAD COMMITED
командаDML
, которой требуется доступ к строке, заблокированной другой транзакцией, будет ждать снятия этой блокировки.SET TRANSACTION USE ROLLBACK SEGMENT
имя сегмента — назначает текущей транзакции заданный сегмент отката и определяет ей доступ «только для чтения». Не может использоваться совместно с командойSET TRANSACTION READ ONLY
.
Механизм сегментов отката считается устаревшим; вместо него следует использовать средства автоматического управления отменой, введенные в Oracle9i.
Команда LOCK TABLE
Команда блокирует всю таблицу базы данных в указанном режиме. Блокировка запрещает или разрешает модификацию данных таблицы со стороны других транзакций на то время, пока вы с ней работаете. Синтаксис команды LOCK TABLE
:
LOCK TABLE
список_таблиц IN режим_блокировки MODE [NOWAIT];
Здесь список таблиц — список из одной или нескольких таблиц (локальных таблиц/пред- ставлений или доступных через удаленное подключение), а режим блокировки — один из шести режимов: ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE.
Если команда содержит ключевое слово NOWAIT
, база данных не ждет снятия блокировки в том случае, если нужная таблица заблокирована другим пользователем, и выдает сообщение об ошибке. Если ключевое слово NOWAIT
не указано, Oracle ждет освобождения таблицы в течение неограниченно долгого времени. Блокировка таблицы не мешает другим пользователям считывать из нее данные.
Примеры допустимых команд LOCK TABLE
:
LOCK TABLE emp IN ROW EXCLUSIVE MODE;
LOCK TABLE emp, dept IN SHARE MODE NOWAIT;
LOCK TABLE scott.emp@new_york IN SHARE UPDATE MODE;
Там, где это возможно, используйте стандартные средства блокировки Oracle
. Команду LOCK TABLE
в приложениях следует использовать только в крайних случаях и с величайшей осторожностью.
Вас заинтересует / Intresting for you:
20. Обработка транзакций
20.1. Что такое транзакция
Транзакции представляют собой блоки из операторов SQL, которые должны выполняться в пакетном режиме.
Обработка транзакций обеспечивает сохранение целостности базы данных за счет того, что пакеты операций SQL полностью или не выполняются вовсе.
Рассмотрим процесс добавления нового заказа по этапам.
1. Проверка, содержится ли информация о клиенте в базе данных. Если нет, такая информация добавляется.
2. Выборка идентификатора клиента.
3. Добавление строки в таблицу Orders, связывающую строку с идентификатором клиента.
4. Выборка идентификатора нового заказа, присвоенного ему в таблице Orders.
Рекомендуемые материалы
5. Добавление одной строки в таблицу OrderItems для каждого заказанного предмета, соотнесение его с таблицей Orders посредством выбранного идентификатора и с таблицей Products посредством идентификатора продукта.
Теперь предположим, что какая-то ошибка в базе данных, например, нехватка места на диске, ограничения, связанные с безопасностью, блокировка таблицы, помешала завершить эту последовательность действий.
Что в этом случае случится с данными?
Хорошо, если ошибка произойдет после добавления информации о клиенте в таблицу, но до того как она будет добавлена в таблицу Orders – в этом случае проблем не будет, так как можно иметь данные о клиентах без заказов. При повторном выполнении последовательности добавленная запись о клиенте будет возвращена и использована. Можно будет продолжить работу с того места, на котором остановились.
На что будет, если ошибка произойдет после того, как была добавлена строка в таблицу Orders, но до того, как будут добавлены строки в таблицу OrderItems? Теперь в базе данных будет присутствовать пустой заказ.
Еще будет хуже, если система сделает ошибку в процессе добавления строк в таблицу OrderItems? В этом случае в базу данных заказ будет внесен лишь частично, и мы даже не будем знать об этом.
Как решается эта проблема? Необходимо применить транзактную организацию обработки данных, т.е. обработку транзакций.
Обработка транзакций – это механизм, используемый для управления наборами операций SQL, которые должны быть выполнены в пакете, т.е. таким образом, чтобы в базу данных не могли попасть результаты частичного выполнения этого пакета операций. При обработке транзакций можно быть уверенным в том, что выполнение набора операций не было прервано на середине – они были выполнены все, или не была выполнена ни одна из них. Если ошибки не произошло, результаты работы всего набора операторов записываются в таблицах базы данных. Если произошла ошибка, должна быть выполнена отмена всех операций, чтобы возвратить базу данных в известное и безопасное состояние.
Возвращаясь к примеру, процесс должен выполняться так.
1. Проверка, содержится ли информация о клиенте в базе данных. Если нет, такая информация добавляется.
2. Фиксация информации о клиенте.
3. Выборка идентификатора клиента.
4. Добавление строки в таблицу Orders, связывающую строку с идентификатором клиента.
5. Если во время добавления строки в таблицу Orders происходит ошибка, операция отменяется.
6. Выборка идентификатора нового заказа, присвоенного ему в таблице Orders.
7. Добавление одной строки в таблицу OrderItems для каждого заказанного предмета, соотнесение его с таблицей Orders посредством выбранного идентификатора и с таблицей Products посредством идентификатора продукта.
8. Если в процессе добавления строк в таблицу OrderItems происходит ошибка, добавление всех строк в таблицу OrderItems отменяется.
При работе с транзакциями определяются термины:
· Транзакция (Transaction). Блок операторов SQL.
· Отмена (Rollback). Процесс аннулирования указанных операторов SQL. (Другое название — откат).
· Фиксация (Commit). Запись несохраненных операторов SQL в таблицы базы данных.
· Точка сохранения (Savepoint). Временное состояние в ходе выполнения транзакции, в которое можно вернуться после отмены части операций пакета, в отличие от отмены всей транзакции. Иногда это состояние называют «точка отката».
Обработка транзакций используется в ходе управления действием операторов INSERT, UPDATE и DELETE, а также CREATE, DROP. Нет смысла отменять действие оператора SELECT.
20.2. Управляемые транзакции
Точный синтаксис, используемый для обработки транзакций, для разных СУБД различен.
Чтобы сделать транзакцию управляемой, нужно разбить ее SQL-операторы на логические части и явно указать, когда может быть выполнена отмена, а когда нет.
В некоторых СУБД требуется, чтобы явно отметили начало и конец каждого блока операторов транзакции. Например, в SQL Server нужно сделать следующее:
BEGIN TRANSACTION
. . .
COMMIT TRANSACTION
Все операторы, заключенные между BEGIN TRANSACTION и COMMIT TRANSACTION, должны быть выполнены, или не выполнены.
В СУБД MySQL это выглядит так:
START TRANSACTION
. . .
20.3. Использование оператора ROLLBACK
Оператор ROLLBACK используется для отмены операторов SQL. Это записывается так:
DELETE FROM Orders;
ROLLBACK;
В примере выполняется и сразу же, посредством оператора ROLLBACK, аннулируется операция DELETE. Это не самый полезный пример, он показывает, что будучи включенными в блок транзакции, операции DELETE (INSERT и UPDATE) не являются окончательными.
20.4. Использование оператора COMMIT
Обычно после выполнения операторов SQL результаты записываются непосредственно в таблицы баз данных. Это называется неявная фиксация – операция фиксации (сохранения или записи) выполняется автоматически.
Однако внутри блока транзакции фиксация неявно может и не проводиться. Это зависит от того, с какой СУБД вы работаете. Некоторые СУБД трактуют завершение транзакции как неявную фиксацию.
Для безусловного выполнения неявной фиксации используется оператор COMMIT. Пример для SQL Server:
BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION
В примере заказ номер 12345 полностью удаляется из системы. Поскольку это приводит к обновлению двух таблиц базы данных, Orders и OrderItems, блок транзакции применяется для того, чтобы заказ не мог быть удален лишь частично. Конечный оператор COMMIT записывает изменения только в случае, если не произошло ошибки. Если первый оператор будет выполнен, а второй, из=за ошибки, не выполнен, удаление не будет зафиксировано.
Чтобы выполнить то же самое в СУБД Oracle, нужно сделать следующее:
DELETE OrderItems WHERE order_num = 12345;
DELETE Orders WHERE order_num = 12345;
COMMIT;
20.5. Использование точек сохранения
Простые операторы ROLLBACK и COMMIT позволяют записывать или отменять транзакции в целом. Хотя это вполне применимо по отношению к простым транзакциям, для более сложных могут понадобиться частичные фиксации или отмены.
Например, процесс добавления заказа, описанный выше, представляет собой одну транзакцию. Если произойдет ошибка, база данных вернется в состояние, когда строка в таблицу Orders еще не была добавлена. Но вряд ли нужно отменить добавление данных в таблицу Customers, если оно было сделано.
Для отмены части транзакции необходимо иметь возможность размещение метое в важных точках блока транзакции. Потом, если понадобится отмена, можно вернуть базу данных в состояние, соответствующее одной из меток.
В языке SQL эти метки называются точками сохранения (savepoints). Для создания такой точки в СУБД MySQL и Oracle применяется оператор SAVEPOINT:
SAVEPOINT deletel;
В SQL Server это будет так:
Лекция 11 — Разработка системы адаптивного управления — лекция, которая пользуется популярностью у тех, кто читал эту лекцию.
SAVE TRANSACTION deletel;
Каждая точка сохранения должна иметь уникальное имя, идентифицирующее ее таким образом, чтобы, когда выполняется отмена, СУБД знала, в какую точку она должна вернуться. Чтобы выполнить отмену действия всех операторов после этой точки, в СУБД SQL Server нужно выполнить:
ROLLBACK TRANSACTIOM delete;
В MySQL и Oracle это так:
ROLLBACK TO delete;
Чем больше точек сохранения, тем лучше.
Приветствую всех посетителей сайта Info-Comp.ru! В этом материале мы с Вами подробно рассмотрим транзакции языка T-SQL, Вы узнаете, что это такое, для чего они нужны, а также какие команды управления транзакциями существуют в T-SQL.
Заметка! T-SQL – это расширение языка SQL, реализованное в Microsoft SQL Server. Более подробно об этом можете почитать в статье – Что такое T-SQL. Подробное описание для начинающих.
Содержание
- Транзакции в T-SQL
- Свойства транзакции
- Команды управления транзакциями в T-SQL
- Примеры транзакций в T-SQL
- Исходные данные для примеров
- Простой пример транзакции в T-SQL
- Пример транзакции в T-SQL с обработкой ошибок
- Уровни изоляции транзакций в T-SQL
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
- SNAPSHOT и READ COMMITTED SNAPSHOT
- Побочные эффекты параллелизма
- Включение уровня изоляции в T-SQL
Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе, или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены. Другими словами, если одна команда или инструкция внутри транзакции завершилась с ошибкой, то все, что было отработано перед ней, также отменяется, даже если предыдущие команды завершились успешно.
Транзакции очень полезны и просто незаменимы в тех случаях, когда Вам необходимо реализовывать бизнес логику в базе данных Microsoft SQL Server, которая предполагает многошаговые операции, где каждый шаг логически связан с другими шагами.
По сути каждая отдельная инструкция языка T-SQL является транзакцией, это называется «Автоматическое принятие транзакций» или «Неявные транзакции», но также есть и явные транзакции, это когда мы сами явно начинаем транзакцию и также явно заканчиваем ее, т.е. делаем все это с помощью специальных команд.
Чтобы понять, как работают транзакции и для чего они нужны, давайте рассмотрим классический пример, который наглядно показывает необходимость использования транзакций.
Допустим, у Вас есть хранимая процедура, которая осуществляет перевод средств с одного счета на другой, соответственно, как минимум у Вас будет две операции в этой процедуре, снятие средств, и зачисление средств, например, две инструкции UPDATE.
Заметка! Назначение хранимых процедур в языке T-SQL.
Но в каждой из этих операций может возникнуть ошибка и инструкция не выполнится. А теперь представьте, что первая инструкция снимает деньги, она выполнилась успешно, вторая инструкция зачисляет деньги и в ней возникла ошибка, без транзакции снятые деньги просто потеряются, так как они никуда не будут зачислены.
Чтобы этого не допустить, все SQL инструкции, которые логически что-то объединяет, в данном случае все операции, связанные с переводом средств, пишут внутри транзакции, и тогда, если наступит подобная ситуация, все изменения будут отменены, т.е. деньги вернутся обратно на счет.
Транзакции можно сочетать с обработкой и перехватом ошибок TRY…CATCH, иными словами, Вы отслеживаете ошибки в Вашем блоке инструкций и если они появляются, то в блоке CATCH Вы откатываете транзакцию, т.е. отменяете все изменения, которые были успешно выполнены до возникновения ошибки в транзакции.
Транзакции – это отличный механизм обеспечения целостности данных.
Свойства транзакции
У транзакции есть 4 очень важных свойства:
- Атомарность – все команды в транзакции либо полностью выполняются, и соответственно, фиксируются все изменения данных, либо ничего не выполняется и ничего не фиксируется;
- Согласованность – данные, в случае успешного выполнения транзакции, должны соблюдать все установленные правила в части различных ограничений, первичных и внешних ключей, определенных в базе данных;
- Изоляция – механизм предоставления доступа к данным. Транзакция изолирует данные, с которыми она работает, для того чтобы другие транзакции получали только согласованные данные;
- Надежность – все внесенные изменения фиксируются в журнале транзакций и данные считаются надежными, если транзакция была успешно завершена. В случае сбоя SQL Server сверяет данные, записанные в базе данных, с журналом транзакций, если есть успешно завершенные транзакции, которые не закончили процесс записи всех изменений в базу данных, они будут выполнены повторно. Все действия, выполненные не подтвержденными транзакциями, отменяются.
Заметка! Чем отличаются функции от хранимых процедур в T-SQL.
Команды управления транзакциями в T-SQL
В T-SQL для управления транзакциями существуют следующие основные команды:
- BEGIN TRANSACTION (можно использовать сокращённую запись BEGIN TRAN) – команда служит для определения начала транзакции. В качестве параметра этой команде можно передать и название транзакции, полезно, если у Вас есть вложенные транзакции;
- COMMIT TRANSACTION (можно использовать сокращённую запись COMMIT TRAN) – с помощью данной команды мы сообщаем SQL серверу об успешном завершении транзакции, и о том, что все изменения, которые были выполнены, необходимо сохранить на постоянной основе;
- ROLLBACK TRANSACTION (можно использовать сокращённую запись ROLLBACK TRAN) – служит для отмены всех изменений, которые были внесены в процессе выполнения транзакции, например, в случае ошибки, мы откатываем все назад;
- SAVE TRANSACTION (можно использовать сокращённую запись SAVE TRAN) – данная команда устанавливает промежуточную точку сохранения внутри транзакции, к которой можно откатиться, в случае возникновения необходимости.
Примеры транзакций в T-SQL
Давайте рассмотрим примеры транзакций, реализованные на языке T-SQL.
Исходные данные для примеров
Но сначала нам необходимо создать тестовые данные для нашего примера.
Для этого выполните следующую инструкцию.
--Создание таблицы CREATE TABLE Goods ( ProductId INT IDENTITY(1,1) NOT NULL, ProductName VARCHAR(100) NOT NULL, Price MONEY NULL, ); --Добавление данных в таблицу INSERT INTO Goods(ProductName, Price) VALUES ('Системный блок', 50), ('Клавиатура', 30), ('Монитор', 100); SELECT ProductId, ProductName, Price FROM Goods;
Заметка! Создание таблиц в Microsoft SQL Server (CREATE TABLE) – подробная инструкция.
Простой пример транзакции в T-SQL
В данном примере у нас всего две инструкции, которые изменяют данные, но допустим, что они взаимосвязаны, т.е. они обе обязательно должны выполниться вместе или не выполниться также вместе.
Поэтому мы решили эти инструкции объединить в одну транзакцию.
Сначала мы открываем транзакцию командой BEGIN TRANSACTION, далее пишем все необходимые инструкции, которые мы хотим объединить в транзакцию.
После этого командой COMMIT TRANSACTION мы сохраняем все внесенные изменения.
В данном случае у нас нет никаких ошибок, все инструкции выполнились успешно. Как результат, транзакция завершена также успешно и все изменения сохранены на постоянной основе командой COMMIT TRANSACTION.
BEGIN TRANSACTION --Инструкция 1 UPDATE Goods SET Price = 70 WHERE ProductId = 1; --Инструкция 2 UPDATE Goods SET Price = 40 WHERE ProductId = 2; COMMIT TRANSACTION SELECT ProductId, ProductName, Price FROM Goods;
Однако, если в любой из инструкций возникнет ошибка, транзакция не завершится, и все изменения не сохранятся.
При этом, стоит помнить о том, что ошибки с определённым уровнем серьезности, например, ошибки, связанные с нарушением ограничений, не влекут за собой автоматический откат всех изменений внесенных текущей транзакцией, поэтому всегда необходимо использовать или инструкцию SET XACT_ABORT ON, или обработку ошибок (допускается и совместное использование).
Например, если во второй инструкции мы попытаемся записать в столбец Price какое-нибудь текстовое значение, то у нас возникнет ошибка, и изменения, внесённые первой инструкцией, не зафиксируются на постоянной основе.
Пример транзакции в T-SQL с обработкой ошибок
В языке T-SQL существует механизм перехвата и обработки ошибок – конструкция TRY… CATCH.
Эту конструкцию можно использовать для отслеживания появления возможных ошибок внутри транзакции и в случае появления таких ошибок предпринять определенные действия.
Сначала мы открываем блок для обработки ошибок, затем открываем транзакцию командой BEGIN TRANSACTION, далее пишем наши инструкции, например, те же самые две инструкции UPDATE.
После этого закрываем блок TRY, открываем блок CATCH, в котором в случае возникновения ошибки мы откатываем все изменения командой ROLLBACK TRANSACTION. Также мы принудительно завершаем нашу инструкцию командой RETURN.
Если ошибок нет, то в блок CATCH мы, соответственно, не попадаем и у нас выполнится команда COMMIT TRANSACTION, которая сохранит все изменения.
В этом примере нет ошибок, поэтому транзакция завершена успешно.
Заметка! Обработка ошибок в языке T-SQL – конструкция TRY CATCH.
BEGIN TRY --Начало транзакции BEGIN TRANSACTION --Инструкция 1 UPDATE Goods SET Price = 70 WHERE ProductId = 1; --Инструкция 2 UPDATE Goods SET Price = 40 WHERE ProductId = 2; END TRY BEGIN CATCH --В случае непредвиденной ошибки --Откат транзакции ROLLBACK TRANSACTION --Выводим сообщение об ошибке SELECT ERROR_NUMBER() AS [Номер ошибки], ERROR_MESSAGE() AS [Описание ошибки] --Прекращаем выполнение инструкции RETURN END CATCH --Если все хорошо. Сохраняем все изменения COMMIT TRANSACTION GO SELECT ProductId, ProductName, Price FROM Goods;
А в этом примере мы намерено допускаем ошибку во второй инструкции. Поэтому управление передается в блок CATCH, где мы откатываем все изменения, возвращаем номер и описание ошибки и принудительно завершаем всю инструкцию командой RETURN.
Первая инструкция отработала нормально, но ее изменения не были сохранены, так как вторая инструкция выполнена с ошибкой.
Заметка! Чем отличается инструкция THROW от RAISERROR в T-SQL.
Уровни изоляции транзакций в T-SQL
Во время выполнения транзакции все данные, над которыми производятся изменения, блокируются, до завершения транзакции, так как, когда один процесс изменяет данные, другой процесс не может одновременно изменять их. В SQL сервере существует механизм, который блокирует (изолирует) данные во время выполнения транзакции. У данного механизма есть несколько уровней изоляции, каждый из которых определяет степень блокировки данных.
Давайте подробней рассмотрим уровни изоляции.
READ UNCOMMITTED
Самый низкий уровень, при котором SQL сервер разрешает так называемое «грязное чтение». Грязным чтением называют считывание неподтвержденных данных, иными словами, если транзакция, которая изменяет данные, не завершена, другая транзакция может получить уже измененные данные, хотя они еще не зафиксированы и могут отмениться.
READ COMMITTED
Этот уровень уже запрещает грязное чтение, в данном случае все процессы, запросившие данные, которые изменяются в тот же момент в другой транзакции, будут ждать завершения этой транзакции и подтверждения фиксации данных. Данный уровень по умолчанию используется SQL сервером.
REPEATABLE READ
На данном уровне изоляции запрещается изменение данных между двумя операциями чтения в одной транзакции. Здесь происходит запрет на так называемое «неповторяющееся чтение» или «несогласованный анализ». Другими словами, если в одной транзакции есть несколько операций чтения, данные будут блокированы и их нельзя будет изменить в другой транзакции. Таким образом, Вы избежите ситуации, когда вначале транзакции Вы запросили данные, провели их анализ (некое вычисление), в конце транзакции запросили те же самые данные, а они уже отличаются от первоначальных, так как они были изменены другой транзакцией.
Также уровень REPEATABLE READ, как и остальные, запрещает «Потерянное обновление» – это когда две транзакции сначала считывают одни и те же данные, а затем изменяют их на основе неких вычислений, в результате обе транзакции выполнятся, но данные будут те, которая зафиксировала последняя операция обновления. Это происходит потому, что данные в операциях чтения в начале этих транзакций не были заблокированы.
SERIALIZABLE
Данный уровень исключает чтение «фантомных» записей. Фантомные записи – это те записи, которые появились между началом и завершением транзакции. Иными словами, в начале транзакции Вы запросили определенные данные, в конце транзакции Вы запрашиваете их снова с тем же фильтром, но там уже есть и новые данные, которые добавлены другой транзакцией. Более низкие уровни изоляции не блокировали строки, которых еще нет в таблице, данный уровень блокирует все строки, соответствующие фильтру запроса, с которыми будет работать транзакция, как существующие, так и те, что могут быть добавлены.
SNAPSHOT и READ COMMITTED SNAPSHOT
Также существуют уровни изоляции, алгоритм которых основан на версиях строк, это
- SNAPSHOT
- READ COMMITTED SNAPSHOT
Иными словами, SQL Server делает снимок и хранит последние версии подтвержденных строк. В данном случае, клиенту не нужно ждать снятия блокировок, пока одна транзакция изменит данные, он сразу получает последнюю версию подтвержденных строк. Следует отметить, что уровни изоляции, основанные на версиях строк, замедляют операции обновления и удаления, так как перед этими операциями сервер делает и копирует снимок строк во временную базу данных.
SNAPSHOT – уровень хранит строки, подтверждённые на момент начала транзакции, соответственно, именно эти строки будут считаны в случае обращения к ним из другой транзакции. Данный уровень исключает повторяющееся и фантомное чтение примерно так же, как уровень SERIALIZABLE.
READ COMMITTED SNAPSHOT – этот уровень изоляции работает практически так же, как уровень SNAPSHOT, с одним отличием, он хранит снимок строк, которые подтверждены на момент запуска команды, а не транзакции, как в SNAPSHOT.
Заметка! Обзор Azure Data Studio. Что это за инструмент и для чего он нужен.
Побочные эффекты параллелизма
На основе вышеизложенного мы можем выделить несколько побочных эффектов, которые могут возникнуть в результате параллельного использования данных:
- Потерянное обновление (Lost Update) – при одновременном изменении данных разными транзакциями одно из изменений будет потеряно;
- Грязное чтение (Dirty Read) – чтение неподтвержденных данных;
- Неповторяющееся чтение (Non-Repeatable Read) – чтение измененных данных в рамках одной транзакции;
- Фантомное чтение (Phantom Reads) – чтение записей, которые появились между началом и завершением транзакции.
Каждый из уровней изоляции устраняет определенные побочные эффекты. В таблице ниже приведены сводные данные.
Побочный эффект / Уровень изоляции | Потерянное обновление | Грязное чтение | Неповторяющееся чтение | Фантомные записи |
READ UNCOMMITTED | Устраняет | Не устраняет | Не устраняет | Не устраняет |
READ COMMITTED | Устраняет | Устраняет | Не устраняет | Не устраняет |
REPEATABLE READ | Устраняет | Устраняет | Устраняет | Не устраняет |
SERIALIZABLE | Устраняет | Устраняет | Устраняет | Устраняет |
SNAPSHOT | Устраняет | Устраняет | Устраняет | Устраняет |
READ COMMITTED SNAPSHOT | Устраняет | Устраняет | Устраняет | Устраняет |
Включение уровня изоляции в T-SQL
Для того чтобы включить тот или иной уровень изоляции для всей сессии, необходимо выполнить команду SET TRANSACTION ISOLATION LEVEL и указать название уровня изоляции.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Также для уровней SNAPSHOT и READ COMMITTED SNAPSHOT предварительно необходимо включить параметр базы данных ALLOW_SNAPSHOT_ISOLATION для уровня изоляции SNAPSHOT и READ_COMMITTED_SNAPSHOT для уровня READ COMMITTED SNAPSHOT.
Например
ALTER DATABASE TestDB SET ALLOW_SNAPSHOT_ISOLATION ON;
Заметка! Если Вас интересует язык SQL, то рекомендую почитать книгу «SQL код» – это самоучитель по языку SQL для начинающих программистов. В ней язык SQL рассматривается как стандарт, чтобы после прочтения данной книги можно было работать с языком SQL в любой системе управления базами данных.
На сегодня это все, надеюсь, материал был Вам полезен, до новых встреч!
12. Транзакции
В этой главе дается определение транзакции и описывается, как БД обрабатывает транзакции.
Введение в транзакции
Транзакция – это логическая, атомарная единица работы, содержащая один или несколько операторов SQL.
Транзакция группирует SQL-инструкции таким образом, что либо все они фиксируются, что означает, что они применяются к БД, либо все откатываются, что означает, что они удаляются из БД. БД Oracle присваивает каждой транзакции уникальный идентификатор, называемый transaction ID.
Все транзакции Oracle соблюдают основные свойства транзакции БД, известные как свойства ACID. ACID – это аббревиатура от следующего:
-
Атомарность
Выполняются все задачи транзакции или не выполняется ни одна из них. Частичных транзакций не существует. Например, если транзакция начинает обновлять 100 строк, но система завершается сбоем после 20 обновлений, то БД откатывает изменения в эти 20 строк. -
Согласованность (Consistency)
Транзакция переводит БД из одного согласованного состояния в другое. Например, в банковской транзакции, которая дебетует сберегательный счет и зачисляет средства на расчетный счет, сбой не должен приводить к тому, что БД зачисляет средства только на один счет, что привело бы к несогласованности данных. -
Изолированность
Эффект транзакции не виден другим транзакциям до тех пор, пока транзакция не будет зафиксирована. Например, один пользователь, обновляющий таблицуhr.employees
, не видит незафиксированных изменений вemployees
, внесенных одновременно другим пользователем. Таким образом, пользователям кажется, что транзакции выполняются последовательно. -
Долговечность
Изменения, внесенные зафиксированными транзакциями, являются постоянными. После завершения транзакции БД с помощью своих механизмов восстановления гарантирует, что изменения, внесенные в транзакцию, не будут потеряны.
Использование транзакций является одним из наиболее важных отличий между СУБД и файловой системой.
Пример транзакции: дебет и кредит счета
Для иллюстрации концепции транзакции, рассмотрим банковскую БД.
Когда клиент переводит деньги со сберегательного счета на расчетный счет, транзакция должна состоять из трех отдельных операций:
-
Уменьшение сберегательного счета
-
Увеличение расчетного счета
-
Запись о транзакции в журнале транзакций
БД Oracle должна допускать две ситуации. Если все три инструкции SQL поддерживают баланс учетных записей в надлежащем состоянии, то последствия транзакции могут быть применены к БД. Однако, если такая проблема, как нехватка средств, неверный номер счета или аппаратный сбой, не позволяет выполнить одну или две операции из транзакции, БД должна выполнить откат всей транзакции, чтобы баланс всех счетов был правильным.
Следующий рисунок иллюстрирует банковскую транзакцию. Первая операция вычитает 500 долларов со сберегательного счета 3209. Вторая операция добавляет 500 долларов к текущему счету 3208. Третья инструкция вставляет запись о передаче в таблицу журнала. Заключительный оператор фиксирует транзакцию.
Структура транзакции
Транзакция БД состоит из одного или нескольких операторов.
В частности, транзакция состоит из одного из следующих действий:
-
Один или несколько операторов языка обработки данных (DML), которые вместе представляют собой атомарное изменение БД
-
Оператор языка определения данных (DDL)
Транзакция имеет начало и конец.
Начало транзакции
Транзакция начинается при выполнении первого исполняемого SQL-оператора.
Исполняемый SQL-оператор – это SQL-оператор, который генерирует вызовы экземпляра БД, включая инструкции DML и DDL и инструкцию SET TRANSACTION
.
Когда транзакция начинается, БД Oracle назначает транзакцию доступному сегменту Undo, чтобы записать Undo-записи для новой транзакции. Идентификатор транзакции не выделяется до тех пор, пока не будут выделены Undo-сегмент и слот таблицы транзакций, что происходит во время первой инструкции DML. Идентификатор транзакции уникален для транзакции и представляет собой номер сегмента отмены, слот и порядковый номер.
В следующем примере выполняется инструкция UPDATE
для начала транзакции и запрашивается V$TRANSACTION
для получения подробной информации о транзакции:
SQL> UPDATE hr.employees SET salary=salary;
107 rows updated.
SQL> SELECT XID AS "txn id", XIDUSN AS "undo seg", XIDSLOT AS "slot",
2 XIDSQN AS "seq", STATUS AS "txn status"
3 FROM V$TRANSACTION;
txn id undo seg slot seq txn status
---------------- ---------- ---------- ---------- ----------------
0600060037000000 6 6 55 ACTIVE
Окончание транзакции
Транзакция может завершиться при различных обстоятельствах.
Транзакция завершается, когда выполняется любое из следующих действий:
-
Пользователь выдает инструкцию COMMIT или ROLLBACK без указания SAVEPOINT.
При фиксации пользователь явно или неявно запросил, чтобы изменения в транзакции стали постоянными. Изменения, внесенные транзакцией, являются постоянными и видны другим пользователям только после фиксации транзакции. -
Пользователь запускает команду DDL, такую как
CREATE
,DROP
,RENAME
илиALTER
.
БД выдает неявный оператор COMMIT до и после каждого оператора DDL. Если текущая транзакция содержит инструкции DML, то Oracle Database сначала фиксирует транзакцию, а затем запускает и фиксирует инструкцию DDL как новую транзакцию с одним оператором. -
Пользователь обычно завершает работу с большинством утилит и инструментов Oracle Database utilities, в результате чего текущая транзакция неявно фиксируется. Поведение фиксации при отключении пользователя зависит от приложения и настраивается.
Примечание: Приложения всегда должны явно фиксировать или отменять транзакции перед завершением работы программы. -
Клиентский процесс завершается ненормально, что приводит к неявному откату транзакции с использованием метаданных, хранящихся в таблице транзакций, и сегмента Undo.
После завершения одной транзакции следующая исполняемая инструкция SQL автоматически запускает следующую транзакцию. В следующем примере выполняется UPDATE
для запуска транзакции, завершается транзакция с помощью инструкции ROLLBACK
, а затем выполняется UPDATE
для запуска новой транзакции (обратите внимание, что идентификаторы транзакций разные):
SQL> UPDATE hr.employees SET salary=salary;
107 rows updated.
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
XID STATUS
---------------- ----------------
0800090033000000 ACTIVE
SQL> ROLLBACK;
Rollback complete.
SQL> SELECT XID FROM V$TRANSACTION;
no rows selected
SQL> UPDATE hr.employees SET last_name=last_name;
107 rows updated.
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
XID STATUS
---------------- ----------------
0900050033000000 ACTIVE
Атомарность на уровне оператора
БД Oracle поддерживает атомарность на уровне оператора, что означает, что SQL-оператор является атомарной единицей работы и либо полностью выполняется успешно, либо завершается с ошибкой.
Успешный оператор отличается от зафиксированной транзакции. Один SQL-оператор выполняется успешно, если БД анализирует и запускает его без ошибок как атомарную единицу, например, когда все строки изменяются при многострочном обновлении.
Если SQL-оператор вызывает ошибку во время выполнения, значит, он не является успешным, и поэтому все последствия оператора отменяются. Эта операция представляет собой откат на уровне оператора. Эта операция имеет следующие характеристики:
-
Оператор SQL, который не выполняется успешно, приводит к потере только работы, которую он выполнил бы сам.
Неудачное выполнение оператора не приводит к потере какой-либо работы, которая предшествовала ему в текущей транзакции. Например, если выполнение второго оператора по обновлению в “Примере транзакции: Дебет и кредит счета” вызывает ошибку и выполняется откат, то работа, выполненная первым оператором поUPDATE
, не откатывается. Первая инструкцияUPDATE
может быть зафиксирована или откатана пользователем явно. -
Эффект отката такой, как если бы оператор никогда не выполнялся.
Любые побочные эффекты атомарного оператора, например, триггеры, вызываемые при выполнении оператора, считаются частью атомарного оператора. Либо вся работа, сгенерированная как часть атомарного оператора, завершается успешно, либо ни одна из них не выполняется.
Примером ошибки, вызывающей откат на уровне оператора, является попытка вставить дубликат первичного ключа. Отдельные операторы SQL, вовлеченные в взаимоблокировку, которая представляет собой конкуренцию за одни и те же данные, также могут вызвать откат на уровне оператора. Однако ошибки, обнаруженные во время синтаксического анализа SQL-оператора, такие как синтаксическая ошибка, еще не были запущены и поэтому не вызывают откат на уровне оператора.
Номера системных изменений
Номер системного изменения (SCN) – это логическая внутренняя временная метка, используемая БД Oracle.
SCNs упорядочивают события, происходящие в БД, что необходимо для удовлетворения ACID-свойств транзакции. БД Oracle использует SCNs для пометки SCN, перед который, как известно, все изменения находятся на диске, чтобы избежать ненужного повтора при восстановлении. БД также использует SCNs для обозначения точки, в которой невозможен повтор для набора данных, чтобы можно было остановить восстановление.
SCN происходит в монотонно возрастающей последовательности. БД Oracle может использовать SCN как часы, поскольку наблюдаемый SCN указывает логический момент времени, а повторные наблюдения возвращают равные или большие значения. Если одно событие имеет более низкий SCN, чем другое событие, то оно произошло в БД в более раннее время. Несколько событий могут использовать один и тот же SCN, что означает, что они произошли в БД в одно и то же время.
У каждой транзакции есть SCN. Например, если транзакция обновляет строку, то БД записывает SCN, в котором произошло это обновление. Другие изменения в этой транзакции имеют тот же SCN. Когда транзакция фиксируется, БД записывает SCN для этой фиксации.
БД Oracle увеличивает SCNs в глобальной области системы (SGA). Когда транзакция изменяет данные, БД записывает новый SCN в Undo-сегмент, назначенный транзакции. Затем процесс записи журнала немедленно записывает запись о фиксации транзакции в оперативный redo-журнал. Запись фиксации имеет уникальный SCN транзакции. Oracle Database также использует SCNs как часть своих механизмов восстановления экземпляров и носителей.
Обзор управления транзакциями
Управление транзакциями – это управление изменениями, вносимыми операторами DML, и группирование инструкций DML в транзакции.
Как правило, разработчики приложений заботятся о контроле транзакций, чтобы работа выполнялась в логических единицах и данные сохранялись согласованными.
Управление транзакциями предполагает использование следующих инструкций, как описано в разделе “Инструкции по управлению транзакциями”:
-
Оператор
COMMIT
завершает текущую транзакцию и делает все изменения, выполненные в транзакции, постоянными.COMMIT
также стирает все точки сохранения в транзакции и снимает блокировки транзакций. -
Оператор
ROLLBACK
отменяет работу, выполненную в текущей транзакции; это приводит к отбрасыванию всех изменений данных с момента последней COMMIT-а или ROLLBACK-а. ИнструкцияROLLBACK TO SAVEPOINT
отменяет изменения с момента последней точки сохранения, но не завершает всю транзакцию. -
Оператор
SAVEPOINT
определяет в транзакции точку, к которой позже можно выполнить откат.
Сеанс, приведенный в таблице 12-1, иллюстрирует основные концепции управления транзакциями.
Наименования транзакций
Имя транзакции – это необязательный, задаваемый пользователем тег, который служит напоминанием о работе, выполняемой транзакцией. Вы называете транзакцию с помощью оператора SET TRANSACTION ... NAME
, который, если используется, должен быть первым оператором транзакции.
В таблице 12-1 первая транзакция была названа sal_update
, а вторая – sal_update 2
.
Именованная транзакция предоставляют следующие преимущества:
-
Проще мониторить длительные транзакции и разрешать сомнительные распределенные транзакции.
-
Можно просматривать имена транзакций вместе с идентификаторами транзакций в приложениях. Например, DBA может просматривать имена транзакций в Oracle Enterprise Manager (Корпоративный менеджер) при мониторинге активности системы.
-
БД записывает имена транзакций в redo-запись аудита транзакций, поэтому вы можете использовать LogMiner для поиска конкретной транзакции в redo-журнале.
-
Можно использовать имена транзакций, чтобы найти конкретную транзакцию в представлениях словаря данных, таких как
V$TRANSACTION
.
Активные транзакции
Активной является транзакция, которая началась, но еще не зафиксирована или не откатана.
В таблице 12-1 первой операцией по изменению данных в транзакции sale_update
является обновление заработной платы Banda
. С момента успешного выполнения этого обновления до завершения транзакции оператором ROLLBACK
транзакция sale_update
активна.
Изменения данных, внесенные транзакцией, являются временными до тех пор, пока транзакция не будет зафиксирована или откатана. Перед завершением транзакции состояние данных будет таким, как показано в следующей таблице.
Таблица 12-2 Состояние данных перед завершением транзакции
Состояние | Описание | Подробности |
---|---|---|
БД Oracle сгенерировала undo-информацию в SGA. | Undo-данные содержат старые значения данных, измененные SQL-операторами транзакции. | Read Consistency in the Read Committed Isolation Level |
БД Oracle сгенерировала redo в оперативном буфере redo-журнала SGA. | Запись redo-журнала содержит изменение в блоке данных и изменение в undo. | Redo Log Buffer |
Были внесены изменения в буферы базы данных SGA. | Изменения данных для зафиксированной транзакции, хранящиеся в буферах базы данных SGA, не обязательно немедленно записываются в файлы данных программой записи БД (DBW). Запись на диск может произойти до или после фиксации. | Database Buffer Cache |
Заблокированы строки, на которые повлияло изменение данных. | Другие пользователи не могут изменять данные в затронутых строках и не могут видеть незафиксированные изменения. | Summary of Locking Behavior |
Точки сохранения
Точка сохранения – это объявленный пользователем промежуточный маркер в контексте транзакции.
Внутренне маркер точки сохранения преобразуется в SCN. Точки сохранения делят длительную транзакцию на более мелкие части.
Если вы используете точки сохранения в длительной транзакции, то позже у вас есть возможность откатить работу, выполненную до текущей точки транзакции, но после объявленной точки сохранения в транзакции. Таким образом, если вы допустите ошибку, вам не нужно повторно отправлять каждое утверждение. Таблица 12-1 создает точку сохранения after_banda_sal
также для того, чтобы обновление зарплаты Greene
можно было откатить до этой точки сохранения.
Откат к точке сохранения
Откат к точке сохранения в незафиксированной транзакции означает отмену любых изменений, внесенных после указанной точки сохранения, но это не означает откат самой транзакции.
Когда транзакция откатывается к точке сохранения, как при выполнении ROLLBACK TO SAVEPOINT after_banda_sal
в таблице 12-1, происходит следующее:
-
БД Oracle откатывает только инструкции, выполненные после точки сохранения.
В таблице 12-1 ОТКАТ К ТОЧКЕ СОХРАНЕНИЯ приводит к откату ОБНОВЛЕНИЯ дляGreene
, но не ОБНОВЛЕНИЯ дляBanda
. -
БД Oracle сохраняет точку сохранения, указанную в инструкции
ROLLBACK TO SAVEPOINT
, но все последующие точки сохранения теряются.
В таблице 12-1 ОТКАТ К ТОЧКЕ СОХРАНЕНИЯ приводит к потере точки сохраненияafter_greene_sal
. -
БД Oracle освобождает все блокировки таблиц и строк, полученные после указанной точки сохранения, но сохраняет все блокировки данных, полученные до точки сохранения.
Транзакция остается активной и может быть продолжена.
Очередь транзакций
В зависимости от сценария, транзакции, ожидающие ранее заблокированных ресурсов, все еще могут быть заблокированы после отката к точке сохранения.
Когда транзакция блокируется другой транзакцией, она ставит в очередь саму блокирующую транзакцию, так что вся блокирующая транзакция должна быть зафиксирована или откатана для продолжения заблокированной транзакции.
В сценарии, показанном в следующей таблице, сеанс 1 выполняет откат к точке сохранения, созданной до выполнения инструкции DML. Однако сеанс 2 по-прежнему заблокирован, поскольку он ожидает завершения транзакции сеанса 1.
Откат транзакции
Откат незафиксированной транзакции отменяет все изменения в данных, которые были выполнены SQL-операторами внутри транзакции.
После отката транзакции последствия работы, выполненной в транзакции, больше не существуют. При откате всей транзакции без ссылки на какие-либо точки сохранения БД Oracle выполняет следующие действия:
-
Отменяет все изменения, внесенные всеми SQL-операторами в транзакции, используя соответствующие сегменты Undo
Запись таблицы транзакций для каждой активной транзакции содержит указатель на все Undo-данные (в обратном порядке применения) для транзакции. БД считывает Undo-данные, отменяет операцию, а затем помечает Undo-запись как примененную. Таким образом, если транзакция вставляет строку, то откат удаляет ее. Если транзакция обновляет строку, то откат отменяет обновление. Если транзакция удаляет строку, то откат повторно вставляет ее. В таблице 12-1 ОТКАТ отменяет обновления заработной платы Грина и Банды. -
Освобождает все блокировки данных, удерживаемые транзакцией
-
Удаляет все точки сохранения в транзакции
В таблице 12-1 при ОТКАТЕ удаляется точка сохраненияafter_banda_sal
. Точка сохраненияafter_greene_sal
была удалена с помощью инструкцииROLLBACK TO SAVEPOINT
. -
Завершает транзакцию
В таблице 12-1 показано, что ОТКАТ оставляет БД в том же состоянии, в котором она была после выполнения первоначальной ФИКСАЦИИ.
Продолжительность отката зависит от объема измененных данных.
Фиксация транзакции
Фиксация завершает текущую транзакцию и делает постоянными все изменения, выполненные в транзакции.
В таблице 12-1 вторая транзакция начинается с sal_update2
и заканчивается явным оператором фиксации. Изменения, внесенные в результате двух инструкций по обновлению, теперь стали постоянными.
Когда транзакция фиксируется, выполняются следующие действия:
-
БД генерирует SCN для ФИКСАЦИИ.
Внутренняя таблица транзакций для связанного табличного пространства Undo записывает, что транзакция была зафиксирована. Соответствующий уникальный SCN транзакции присваивается и записывается в таблицу транзакций. -
Процесс записи журнала (LGWR) записывает оставшиеся записи redo-журнала из буферов redo-журнала в оперативный redo-журнал и записывает SCN транзакции в оперативный redo-журнал. Это атомарное событие представляет собой фиксацию транзакции.
-
БД Oracle освобождает блокировки, удерживаемые в строках и таблицах.
Пользователям, которые были поставлены в очередь в ожидании блокировок, удерживаемых незафиксированной транзакцией, разрешается продолжить свою работу. -
БД Oracle выполняет очистку фиксации.
Если измененные блоки, содержащие данные из зафиксированной транзакции, все еще находятся в SGA, и если ни один другой сеанс не изменяет их, то БД удаляет из блоков информацию о транзакции, связанную с блокировкой (запись ITL).
В идеале,COMMIT
очищает блоки, чтобы последующемуSELECT
не приходилось выполнять эту задачу. Если для определенной строки не существует записиITL
, то она не заблокирована. Если записьITL
существует для определенной строки, то она, возможно, заблокирована, поэтому сеанс должен проверить заголовок undo-сегмента, чтобы определить, была ли зафиксирована эта заинтересованная транзакция. Если заинтересованная транзакция зафиксирована, то сеанс очищает redo-блок. Однако, если ФИКСАЦИЯ ранее очистила ITL, то проверка и очистка не нужны.
Примечание: Поскольку очистка блока генерирует redo, запрос может сгенерировать redo и, таким образом, вызвать запись блоков во время следующей контрольной точки. -
БД Oracle помечает транзакцию как завершенную.
После фиксации транзакции пользователи могут видеть изменения.
Как правило, фиксация – это быстрая операция, независимо от размера транзакции. Скорость фиксации не увеличивается с увеличением размера данных, измененных в транзакции. Самая длинная часть фиксации – это ввод-вывод с физического диска, выполняемый LGWR
. Однако количество времени, затрачиваемого LGWR
, сокращается, поскольку он постепенно записывает содержимое буфера redo-журнала в фоновом режиме.
Поведение по умолчанию заключается в том, что LGWR
синхронно записывает redo в онлайн-журнал redo, а транзакции ожидают, пока буферизованный redo окажется на диске, прежде чем возвращать фиксацию пользователю. Однако для снижения задержки фиксации транзакции разработчики приложений могут указать, что запись redo должна выполняться асинхронно, чтобы транзакциям не нужно было ждать, пока redo будет на диске, и они могли немедленно вернуться из вызова ФИКСАЦИИ.
Обзор охранителя транзакций
Transaction Guard – это API, который приложения могут использовать для обеспечения идемпотентности транзакции, то есть способности БД сохранять гарантированный результат фиксации, который указывает, была ли транзакция зафиксирована и завершена. БД Oracle предоставляет API для JDBC thin, OCI, OCCI и ODP.Net .
Исправляемая ошибка вызвана внешним системным сбоем, не зависящим от логики выполняемого сеанса приложения. Исправимые ошибки возникают после запланированных и незапланированных отключений основных процессов, сетей, узлов, хранилищ и баз данных. Если сбой прерывает соединение между клиентским приложением и БД, то приложение получает сообщение об ошибке отключения. Транзакция, которая выполнялась при разрыве соединения, называется транзакцией-в-полете.
Чтобы решить, отправлять ли транзакцию повторно или вернуть результат (зафиксированный или незафиксированный) клиенту, приложение должно определить результат транзакции-в-полете. До Oracle Database 12c сообщения о фиксации, возвращаемые клиенту, не были постоянными. Проверка транзакции не была гарантией того, что она не будет зафиксирована после проверки, что допускало дублирование транзакций и другие формы логического повреждения. Например, пользователь может обновить веб-браузер при покупке книги онлайн и получить двойную плату за одну и ту же книгу.
Преимущества охранителя транзакций
Начиная с Oracle Database 12c, Transaction Guard предоставляет приложениям инструмент для определения статуса транзакции в процессе выполнения после восстановимого сбоя.
Используя Transaction Guard, приложение может гарантировать, что транзакция выполняется не более одного раза. Например, если приложение книжного онлайн-магазина определяет, что ранее отправленная фиксация завершилась неудачей, то приложение может безопасно отправить ее повторно.
Transaction Guard предоставляет инструмент для одноразововго выполнения, чтобы приложение не производило повторных коммитов. Transaction Guard обеспечивает известный результат для каждой транзакции.
Transaction Guard – это основная функция БД Oracle. Непрерывность работы приложения использует Transaction Guard для маскировки сбоев со стороны конечных пользователей. Без защиты транзакций повторная попытка приложения после ошибки может привести к фиксации повторяющихся транзакций.
Как работает охранитель транзакций
В этом разделе объясняется проблема потерянных сообщений о фиксации и то, как Transaction Guard использует логические идентификаторы транзакций для решения проблемы.
Сообщения о неверном коммите
При проектировании с учетом идемпотентности разработчики должны решить проблему сбоев связи после отправки инструкций фиксации. Сообщения о фиксации не сохраняются в БД и поэтому не могут быть восстановлены после сбоя.
Следующий рисунок представляет собой высокоуровневое представление взаимодействия между клиентским приложением и БД.
В стандартном случае фиксации БД фиксирует транзакцию и возвращает клиенту сообщение об успешном завершении. На рисунке 12-2 клиент отправляет инструкцию фиксации и получает сообщение о том, что связь не удалась. Этот тип сбоя может произойти по нескольким причинам, включая сбой экземпляра БД или отключение сети. В этом сценарии клиент не знает о состоянии транзакции.
После сбоя связи БД может все еще выполнять отправку и не знать, что клиент отключился. Проверка состояния транзакции не гарантирует, что активная транзакция не будет зафиксирована после проверки. Если клиент повторно отправит фиксацию из-за этой устаревшей информации, то БД может повторить транзакцию, что приведет к логическому повреждению.
Логический Transaction ID
Oracle Database решает проблему сбоя связи с помощью глобально-уникального идентификатора, называемого логическим идентификатором транзакции.
Этот идентификатор содержит логический номер сеанса, выделяемый при первом подключении сеанса, и номер текущей фиксации, который обновляется каждый раз, когда сеанс фиксируется или откатывается. С точки зрения приложения логический идентификатор транзакции однозначно идентифицирует последнюю транзакцию БД, отправленную в сеансе, завершившемся с ошибкой.
Для каждого цикла обработки от клиента, в ходе которой совершается одна или несколько транзакций, в БД сохраняется логический идентификатор транзакции. Этот идентификатор может обеспечить идемпотентность транзакции для взаимодействий между приложением и БД при каждом цикле обработки, при котором фиксируются данные.
Протокол “единственной обработки” обеспечивает доступ к результату фиксации, требуя от БД выполнения следующего:
-
Ведёт логический идентификатор транзакции в течение периода хранения, согласованного для повторной попытки
-
Сохраняет логический идентификатор транзакции при фиксации
Во время выполнения транзакции как БД, так и клиент хранят логический идентификатор транзакции. БД предоставляет клиенту логический идентификатор транзакции при аутентификации, при заимствовании из пула подключений и при каждом цикле обработки от драйвера клиента, который выполняет одну или несколько операций фиксации.
Прежде чем приложение сможет определить результат последней транзакции после исправляемой ошибки, приложение получает логический идентификатор транзакции, хранящийся на клиенте, используя Java, OCI, OCCI или ODP.Net API. Затем приложение вызывает процедуру PL/SQL DBMS_APP_CONT.GET_LTXID_OUTCOME
с логическим идентификатором транзакции, чтобы определить результат последней отправки: зафиксировано (true
или false
) и завершено (true
или false
).
При использовании Transaction Guard приложение может воспроизводить транзакции, когда ошибка исправима и последняя транзакция в сеансе не была зафиксирована. Приложение может продолжить работу после завершения последней транзакции и пользовательского вызова. Приложение может использовать Transaction Guard для возврата клиенту известного результата, чтобы клиент мог принять решение о следующем действии.
Пример охранителя транзакций
В этом сценарии сообщение о фиксации теряется из-за исправимой ошибки.
Защита транзакций использует логический идентификатор транзакции для сохранения результата инструкции COMMIT, гарантируя, что результат транзакции известен.
На рисунке 12-3 БД информирует приложение о том, зафиксирована ли транзакция и завершен ли последний вызов пользователя. Затем приложение может вернуть результат конечному пользователю. Возможности заключаются в следующем:
-
Если транзакция зафиксирована и вызов пользователя завершен, то приложение может вернуть результат конечному пользователю и продолжиться.
-
Если транзакция зафиксирована, но вызов пользователя не завершен, то приложение может вернуть результат конечному пользователю с предупреждениями. Примеры включают потерянную привязку или потерянное количество обработанных строк. Некоторые приложения зависят от дополнительной информации, в то время как другие этого не делают.
-
Если пользовательский вызов не был зафиксирован, то приложение может вернуть эту информацию конечному пользователю или безопасно отправить повторно. Соблюдение протокола гарантировано. Когда статус фиксации возвращает значение
false
, фиксация последней отправки блокируется.
Смотри подробнее: Oracle Database Development Guide
Обзор непрерывности работы приложения
Непрерывность работы приложений пытается замаскировать сбои в работе приложений путем замены неполных запросов приложений после незапланированных и запланированных отключений. В этом контексте запрос – это единица работы приложения.
Обычно запрос соответствует операторам DML и другим вызовам БД одного веб-запроса при единственном подключении к БД. В общем случае запрос разграничивается вызовами, выполняемыми между извлечением и регистрацией подключения к БД из пула подключений.
Преимущества непрерывности работы приложения
Основная проблема для разработчиков заключается в том, как скрыть потерянный сеанс БД от конечных пользователей.
Application Continuity пытается решить проблему потерянного сеанса путем восстановления сеанса БД, когда какой-либо компонент прерывает диалог между БД и клиентом. Восстановленный сеанс БД включает в себя все состояния, курсоры, переменные и самую последнюю транзакцию, если таковая существует.
Варианты использования непрерывности работы приложения
В типичном случае клиент отправил запрос в БД, которая создала как транзакционные, так и нетранзакционные состояния.
Состояние на клиенте остается текущим, потенциально с введенными данными, возвращенными данными и кэшированными данными и переменными. Однако состояние сеанса БД, в пределах которого приложение должно работать, теряется.
Если запрос клиента инициировал одну или несколько транзакций, то приложение сталкивается со следующими возможностями:
-
Если был выдан
COMMIT
, то сообщение о фиксации, возвращенное клиенту, не является долговременным. Клиент не знает, зафиксирован ли запрос и в каком состоянии нетранзакционной обработки он был достигнут. -
Если
COMMIT
не был принят или если был принят, но не был выполнен, то транзакция-в-полете откатывается и должна быть повторно отправлена с использованием сеанса в правильном состоянии.
Если воспроизведение прошло успешно, то обслуживание пользователей БД при плановых и незапланированных отключениях не прерывается. Если БД обнаруживает изменения в просмотренных данных и потенциально воздействует на них приложением, то повторное воспроизведение отклоняется. Попытка воспроизведения не выполняется, если превышено время, отведенное для запуска воспроизведения, приложение использует ограниченный вызов или приложение явно отключило воспроизведение с помощью метода disableReplay
.
Непрерывности работы приложения для планового сопровождения
Непрерывность работы приложений при запланированных отключениях позволяет приложениям продолжать работу в течение сеансов базы данных, которые могут быть надежно отключены или перенесены.
Плановое техническое обслуживание не должно нарушать работу приложения. Непрерывность работы приложения позволяет перенести активное рабочее время из его текущего местоположения в новое местоположение, на которое в настоящее время не влияет техническое обслуживание. По истечении интервала прерывания сеансы могут оставаться в экземпляре БД, где планируется техническое обслуживание. Вместо принудительного отключения этих сеансов, Application Continuity может выполнить останов по этим сеансам на сохранившемся сайте и повторно отправить любые транзакции в процессе работы.
Если Application Continuity включена, БД может выполнять следующее:
-
Сообщать во время технического обслуживания об отсутствии ошибок как для входящих, так и для существующих работ.
-
Перенаправлять активные сеансы БД на другие функциональные службы.
-
При необходимости производить перебалансировку сеансов БД данных во время и после технического обслуживания.
Во время планового технического обслуживания производится управление поведением с помощью служебных атрибутов drain_timeout
и stop_option
утилиты SRVCTL
, Global Data Services Control Utility (GDSCTL
) и Oracle Data Guard Broker. Пакет DBMS_SERVICE предоставляет базовую инфраструктуру.
Архитектура непрерывности работы приложения
Ключевыми компонентами непрерывности работы приложения являются среда выполнения, переподключение и повторное воспроизведение.
Этапы заключаются в следующем:
1. Обычное время выполнения
На этом этапе непрерывность работы приложения выполняет следующие задачи:
-
Идентифицирует запросы к БД
-
Решает, являются ли вызовы БД локальными или воспроизводимыми
-
Создает, при необходимости, прокси-объекты для разрешения воспроизводимости и для управления очередями
-
Удерживает исходные вызовы и проверку этих вызовов до тех пор, пока не будет завершен запрос к БД или пока воспроизведения запрещены
2. Переподключение
Эта фаза инициируется исправляемой ошибкой. Непрерывность работы приложения выполняет следующие задачи:
-
Убеждается, что разрешено воспроизведение запросов к БД
-
Управляет временем обработки запросов
-
Получает новое подключение к БД, а затем проверяет, что это допустимый целевой объект БД
-
Использует Transaction Guard для определения того, успешно ли была зафиксирована последняя транзакция (зафиксированные транзакции повторно не отправляются)
3. Повтор
Непрерывность работы приложения выполняет следующие задачи:
-
Воспроизводит вызовы, которые находятся в очереди
-
Отключает воспроизведение, если во время воспроизведения появляются видимые пользователем изменения в результатах
-
Не разрешает фиксацию, но позволяет последнему вызову (который столкнулся с ошибкой) произвести коммит
После успешного воспроизведения запрос продолжается с момента сбоя.
Обзор автономных транзакций
Автономная транзакция – это независимая транзакция, которая может быть вызвана из другой транзакции, которая является основной транзакцией. Вы можете приостановить вызывающую транзакцию, выполнить операции SQL и зафиксировать или отменить их в автономной транзакции, а затем возобновить вызывающую транзакцию.
Автономные транзакции полезны для действий, которые должны выполняться независимо, независимо от того, фиксирует ли вызывающая транзакция или откатывает. Например, в транзакции покупки акций вы хотите зафиксировать данные клиента независимо от того, была ли произведена общая покупка акций. Кроме того, вы хотите записывать сообщения об ошибках в таблицу отладки, даже если общая транзакция откатывается.
Автономные транзакции обладают следующими характеристиками:
-
Автономная транзакция не видит незафиксированных изменений, внесенных основной транзакцией, и не делится блокировками или ресурсами с основной транзакцией.
-
Изменения в автономной транзакции видны другим транзакциям после фиксации автономных транзакций. Таким образом, пользователи могут получить доступ к обновленной информации, не дожидаясь фиксации основной транзакции.
-
Автономные транзакции могут запускать другие автономные транзакции. Кроме ограничений на ресурсы, нет ограничений на то, сколько уровней автономных транзакций может быть вызвано.
В PL/SQL автономная транзакция выполняется в автономной области, которая представляет собой процедуру, помеченную pragma AUTONOMOUS_TRANSACTION
. В этом контексте подпрограммы включают анонимные блоки PL/SQL верхнего уровня, а также подпрограммы и триггеры PL/SQL. Прагма – это директива, которая предписывает компилятору выполнить параметр компиляции. Pragma AUTONOMOUS_TRANSACTION
сообщает БД, что эта процедура при выполнении должна выполняться как новая автономная транзакция, независимая от своей родительской транзакции.
На следующем рисунке показано, как управление переходит от основной процедуры (MT
) к автономной процедуре и обратно. Основная процедура – proc1
, а автономная процедура – proc2
. Автономная процедура может совершить несколько транзакций (AT1
и AT2
), прежде чем управление вернется к основной процедуре.
Рис 12-4. Поток управления транзакциями
Когда вы входите в исполняемый раздел автономной процедуры, основная процедура приостанавливается. Когда вы выходите из автономной процедуры, основная процедура возобновляется.
На рисунке 12-4 COMMIT
внутри proc1
фиксирует не только свою собственную работу, но и любую незавершенную работу, выполненную в его сеансе. COMMIT
внутри proc2
делает постоянной только работу, выполненную в транзакции proc2
. Таким образом, инструкции COMMIT
в транзакциях AT1
и AT2
не оказывают никакого влияния на транзакцию MT
.
Обзор распределенных транзакций
Распределенная транзакция – это транзакция, которая включает в себя одну или несколько инструкций, которые обновляют данные на двух или более различных узлах распределенной БД, используя объект схемы, называемый DBLink.
Распределенная БД — это набор БД в распределенной системе, которые могут отображаться приложениями как единый источник данных. DBLink описывает, как один экземпляр БД может войти в другой экземпляр БД.
В отличие от транзакции в локальной БД, распределенная транзакция изменяет данные в нескольких БД. Следовательно, распределенная обработка транзакций является более сложной, поскольку БД должна координировать фиксацию или откат изменений в транзакции как атомарной единице. Вся транзакция должна быть зафиксирована или откатана. БД Oracle должна координировать управление транзакциями по сети и поддерживать согласованность данных, даже если происходит сетевой или системный сбой.
Двух-фазный COMMIT
Двухфазный механизм фиксации гарантирует, что все частичные БД, участвующие в распределенной транзакции, либо все фиксируют, либо все отменяют инструкции в транзакции. Этот механизм также защищает неявный DML выполняемый ограничениями целостности, удаленными вызовами процедур и триггерами.
При двухфазной фиксации между несколькими БД одна база данных координирует распределенную транзакцию. Инициирующий узел называется глобальным координатором. Координатор запрашивает другие БД, готовы ли они к фиксации. Если какая-либо БД отвечает “нет”, то вся транзакция откатывается. Если все БД проголосуют “за”, то координатор отправит сообщение, чтобы сделать фиксацию постоянной в каждой из БД.
Двухэтапный механизм фиксации прозрачен для пользователей, которые осуществляют распределенные транзакции. Фактически, пользователям даже не нужно знать, что транзакция распределена. Оператор COMMIT, обозначающий завершение транзакции, автоматически запускает механизм двухфазной фиксации. Для включения распределенных транзакций в тело приложения БД не требуется никакого кодирования или сложного синтаксиса инструкций.
Сомнительные транзакции
Сомнительная распределенная транзакция возникает, когда двухфазная фиксация была прервана каким-либо системным или сетевым сбоем.
Например, две БД сообщают координирующей БД, что они были готовы к фиксации, но экземпляр координирующей БД завершает работу с ошибкой сразу после получения сообщений. Две БД, которые готовы к фиксации, теперь остаются зависшими, ожидая уведомления о результатах.
Фоновый процесс recoverer (RECO) автоматически разрешает результаты сомнительных распределенных транзакций. После устранения сбоя и восстановления связи процесс RECO каждой локальной БД Oracle автоматически фиксирует или откатывает любые сомнительные распределенные транзакции последовательно на всех задействованных узлах.
В случае длительного сбоя Oracle Database позволяет каждому локальному администратору вручную зафиксировать или отменить любые распределенные транзакции, которые вызывают сомнения из-за сбоя. Этот параметр позволяет администратору локальной базы данных освободить все заблокированные ресурсы, которые хранятся неопределенно долго из-за длительного сбоя.
Если БД должна быть восстановлена до прошлого времени, то средства восстановления БД позволяют администраторам БД на других сайтах возвращать свои базы данных к более раннему моменту времени. Эта операция гарантирует, что глобальная база данных остается согласованной.