Документация Oracle на русском языке





Сайт посвящен разработке информационных систем с использованием технологий Oracle. На сайте можно найти полезную литературу и документацию на русском языке по программированию и администрированию Oracle.Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации.

Главная :: Карта


Oracle Database или Oracle RDBMS — объектно-реляционная система управления базами данных компании Oracle.



 

DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Транзакции

Транзакция
На предыдущих уроках мы создали таблицы и написали скрипт для ввода тестового набора данных. Скрипт содержит последовательность команд INSERT и UPDATE.
Рисунок 1. Транзакция.
Нужно быть готовыми к тому, что какая-нибудь из команд этого скрипта может выполниться с ошибкой. В этом случае данные в таблицах будут некорректные. Нельзя сказать, что мы правильно ввели тестовый пример. Более того, нам нужно будет как-то исправлять ситуацию. 
Очевидно, что после выполнения скрипта мы должны каким-то образом подтвердить, что результат выполнения команд нас устраивает. 
Если мы отказываемся от этих изменений, то мы должны сказать, изменения каких команд должно быть отменено.
Такая последовательность команд на изменение записей в таблицах называется транзакцией. У этой последовательности есть момент начала и есть момент завершения. 

Начало и завершение транзакции
Транзакция по умолчанию начинается с первой команды, которая изменяет записи в таблицах. Напомню, к этим командам относятся INSERT, UPDATE, DELETE. В момент начала транзакции ORACLE запоминает первую команду и приступает к протоколированию изменений. При этом команды внутри транзакции будут учитывать изменения, которые сделаны предыдущими командами. Это относится и к команде SELECT внутри транзакции. 
На примере добавления тестового набора, мы видели, что команды UPDATE используют данные, которые были "только что" занесены командой INSERT.
Если команда SELECT выполняется вне транзакции, то она не начинает транзакцию, потому что она не изменяет данные. Только читает их из таблиц. 
Транзакция всегда завершается. Это происходит либо явно, либо неявно. 
Явное завершение - когда пользователь вводит команду COMMIT, либо команду ROLLBACK.
Транзакция может быть завершена с фиксацией изменений или с отменой. Команда COMMIT фиксирует изменения, команда ROLLBACK отменяет все сделанные изменения. 
Если в момент завершения мы дадим команду отмены, то наше состояние вернётся в состояние перед началом транзакции.
Неявное завершение транзакции - когда пользователь не вводит команду COMMIT или ROLLBACK. Такое завершение транзакции происходит, когда пользователь вводит команду языка описания данных DML, либо когда он прекращает сеанс, а точнее разрывает его. Например, закрывает программу SQL*Plus по кнопке "Закрыть окно" или клавиатурной комбинацией ALT+F4, или когда по сети происходит сбой и соединение разрывается.

Пакетная передача команд
Снова вернемся к скрипту в учебном примере. Рассмотрим, как он работает. Программа-клиент последовательно выполняет команды из скрипта. Каждая команда передаётся на сервер базы данных и там выполняется. После завершения команды сервер возвращает результат её работы и код завершения. Либо команда завершилась хорошо, без ошибки, либо с ошибкой.
Рисунок 2. Выполнение PL/SQL блока.
Этот способ предполагает активное взаимодействие программы-клиента и сервера базы данных. Такое взаимодействие приводит к увеличению сетевого трафика, времени выполнения скрипта. Потреблению дополнительных ресурсов (памяти, процессорного времени). Кроме того, интенсивное взаимодействие по сети двух программ приводит к увеличению рисков сбоя.
Есть альтернатива. Можно передать на сервер все команды за один раз. Пакетная передача может быть осуществлена с помощью PL/SQL блоков, т.е. небольшой программы на языке программирования PL/SQL.
Для оформления наших команд в форме блока достаточно в начале дописать ключевое слово BEGIN и закончить последовательность команд словом END. Таким образом, все команды будут записаны между ключевыми словами BEGIN и END. Программа-клиент передаёт текст блока серверу базы данных за одно обращение, т.е. весь список команд передаётся один раз. Сервер выполняет все команды в блоке и после этого возвращает код завершения.
Преимущество пакетной передачи команд в том, что уменьшаются риски сбоя, время выполнения скрипта, потребность в вычислительных ресурсах. 
При создании таблиц мы исходили из того, что в них будут храниться записи нескольких счетов. Мы подготовили скрипт, который вводит тестовый набор данных в таблицы. Но при этом мы не учитывали тот факт, что в таблице будут записи разных счетов. В этом уроке мы скрипт доработаем. Ограничим действие команд рамками одного счёта, причём того, с которым работаем. Для этого припишем условия к командам изменения записей UPDATE.
Для этого урока я подготовил файл ins_ex. Он содержит все команды для добавления тестового набора. Перенёс команды из нескольких файлов в один большой. 

Проверка команды ROLLBACK 
1. Убедимся, что в таблицах ничего нет.
@show_ex
2. Запустим скрипт с тестовым набором.
@ins_ex
Скрипт выполнен без ошибок. Первая команда INSERT из скрипта открывает транзакцию.
3. Смотрим содержимое таблиц.
@show_ex
Данные тестового набора добавлены в таблицу. 
Обращаю внимание. Сейчас транзакция открыта. Команды SELECT выводят информацию с учетом изменений, которые сделаны скриптом ins_ex.
4. Вводим команду.
rollback;
Команда выполнена.
Транзакция явно завершена. Изменения отменены, т.е. тестового набора в таблицах не должно быть.
5. Убедимся в том, что таблицы пустые.
@show_ex
Действительно пустые. 
Команда ROLLBACK завершила транзакцию с откатом изменений. Видим, что всё вернулось в исходное состояние, тестового набора нет.

Команда COMMIT
Проверим команду явного завершения транзакции с фиксацией изменений. Команда COMMIT.
1. Таблицы пустые. Добавим тестовый набор.
@ins_ex
Транзакция началась.
2. Убедимся, что тестовый набор добавлен.
@show_ex
Данные добавлены. Транзакция открыта.
3. Вводим команду.
commit;
Команда выполнена.
Транзакция явно завершена. Изменения зафиксированы.
4.Смотрим…
@show_ex
…данные присутствуют. Изменения сохранены.

Неявное завершение транзакции
Проверим неявное завершение транзакции с отменой изменений.
1. Исходное состояние – тестовый набор в таблицах. Удалим его.
@del_ex
Скрипт выполнен без ошибок. 
Транзакция началась – первая команда DELETE начинает транзакцию.
2. Убедимся, что данных нет.
@show_ex
Таблицы пусты.
Транзакция открыта. Команда SELECT внутри транзакции учитывает изменения предыдущих команд.
3. Разорвем сеанс. Закрываем программу SQL*Plus либо щелчком на кнопке "Закрыть окно", либо одновременно нажимаем комбинацию клавиш ALT и F4.
Разорвали сеанс - это не явное завершение транзакции с отменой изменений, т.е. неявный rollback;
4. Запускаем программу SQL*Plus и подключаемся к базе данных.
5. Смотрим содержимое таблиц.
@show_ex
Тестовый набор на месте. Другими словами, действие команд DELETE отменено, разрыв сеанса привел к завершению транзакции и откату изменений.

Выполнение команд с ошибками
Пусть транзакция состоит из последовательности команд. Рассмотрим случай, когда одна из них выполнилась с ошибкой.
1. Вносим изменения в файл ins_ex. Умышленно делаем ошибку, меняем местами номер и дату документа в команде добавления услуг упаковки, т.е. в середине последовательности команд.
Откроем файл в текстовом редакторе. Найдем команду и внесем изменения. Запишем команду в файл с другим именем, например, ins_ex1.sql.
edit ins_ex

insert into exsvc
( exsvc_c
, doc_nd
, doc_dd
, service_n
, tax)
values
( seq_exsvc.NEXTVAL
, '12-sep-2003'
, 137
, 'услуги упаковки'
, 18)
2. Почистим таблицы.
@del_ex
Транзакция началась.
3. Продолжаем транзакцию. Выполним скрипт, который содержит ошибку.
@ins_ex1
Одна из команд выполнена с ошибкой. 
Обращаю внимание. При возникновении ошибки выполнение скрипта продолжилась. Команды после сбоя отработали без ошибок. Смотрите сообщения.
4. Завершаем транзакцию.
commit;
5. Смотрим результат.
@show_ex
Данные в таблицах есть, но это не тестовый набор. Другими словами, сбой всего в одной команде привел к некорректному добавлению тестового набора.
Вывод: программист должен после каждой команды проверять код завершения и принимать решение о продолжении или завершении транзакции.
Ещё вывод: команды завершения транзакции только закрывают транзакцию. Они не проверяют коды выполнения команд, составляющих транзакцию. 
И ещё: фиксируются изменения только тех команд, которые выполнились без ошибок. Изменения будут зафиксированы, даже если одна или несколько команд, входящих в транзакцию, выполнились с ошибками.
 


Платный медицинский лечебно Областной детский диагностический центр.
jAntivirus