Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lekcii (1).doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.44 Mб
Скачать
  1. Транзакции

http://www.intuit.ru/department/database/sql/16/4.html

Транзакция представляет собой команду или группу команд SQL, которые завершаются или отменяются как единое целое.

Классический пример транзакции – пересылка денег через банкомат. Предположим, через банкомат происходит перевод $5000 с накопительного счёта на текущий. Программа вычитает $5000 с накопительного счёта, после чего увеличивает текущий счёт на $5000. Во время работы программы после вычитания денег с накопительного счёта, но до увеличения текущего счёта на банкомате происходит сбой питания. Вопрос: что происходит с $5000? Деньги возвращаются на накопительный счёт, помещаются на текущий счёт или пропадают навеки?

Если эти две команды объединены в транзакцию, проблем нет. Это гарантирует, что обе команды либо успешно завершатся, либо не завершится ни одна из них. Без транзакций существует опасность того, что будет выполнена лишь одна команда.

Каждый из операторов INSERT, UPDATE, DELETE создаёт транзакцию, которая завершается при завершении оператора. Транзакция может состоять также из нескольких операторов. Для управления транзакциями существуют специальные команды.

Синтаксис

Применение

BEGIN { TRAN | TRANSACTION } [имя_транзакции | переменная]

Определение начала транзакции. Имя транзакции может храниться в переменной.

COMMIT { TRAN | TRANSACTION } [имя_транзакции | переменная]

Отметка об успешном завершении транзакции, изменение данных становится постоянным.

COMMIT WORK

Завершение транзакции. Работает аналогично COMMIT TRAN, но без имени транзакции.

ROLLBACK { TRAN | TRANSACTION }

[имя_транзакции | имя_точки_сохранения

| переменная]

Откат изменений до начала транзакции или до точки сохранения. Команда освобождает ресурсы, занятые транзакцией.

ROLLBACK [ WORK ]

Работает аналогично ROLLBACK TRAN, но без имени транзакции.

SAVE { TRAN | TRANSACTION }

{ имя_точки_сохранения | переменная }

Установка точки сохранения внутри транзакции, к которой может выполняться откат. Точка сохранения определяет место, к которому может возвратиться транзакция, если часть транзакции условно отменена.

Если во время транзакции происходят ошибки, выполняется команда ROLLBACK TRAN.

При многопользовательском доступе всегда есть возможность параллельного доступа, т.е. одновременного обращения нескольких пользователей к одним и тем же данным. Из-за этого могут возникать проблемы.

    1. Проблемы параллельного доступа.

При параллельном использовании транзакций могут возникать следующие проблемы:

  • потерянное обновление (lost update);

  • "грязное" чтение (dirty read);

  • неповторяющееся чтение (non-repeatable read);

  • фантомная вставка (phantom insert).

  1. Потерянное обновление может возникнуть в ситуации, когда две транзакции обновляют одни и те же данные.

Предположим, происходит одновременная работа с таблицей ShopTable. Две транзакции открыты различными приложениями.

Транзакция 1

Транзакция 2

SELECT cost FROM ShopTable

WHERE id_product = 1;

UPDATE ShopTable SET cost=100

WHERE id_product = 1;

SELECT cost FROM ShopTable

WHERE id_product = 1;

UPDATE ShopTable SET cost=200

WHERE id_product = 1;

В транзакции 1 изменяется значение поля cost, а затем в транзакции 2 также изменяется значение этого поля. В результате изменение, выполненное первой транзакцией, будет потеряно.

При использовании формулы cost = cost*2 результат был бы другим. Пусть начальное значение cost = 50, тогда транзакция 1 изменит его на cost = 100, после чего транзакция 2 увеличит значение поля ещё в два раза, в итоге cost = 4.

  1. «Грязное» чтение возникает, когда одна транзакция видит не сохранённые изменения, сделанные другой транзакцией, после чего происходит откат первой транзакции.

Транзакция 1

Транзакция 2

SELECT cost FROM ShopTable

WHERE id_product = 1;

UPDATE ShopTable SET cost=cost*2

WHERE id_product = 1;

ROLLBACK WORK;

SELECT cost FROM ShopTable

WHERE id_product = 1;

В транзакции 1 изменяется значение поля cost, а затем транзакция 2 выбирает значение этого поля. После этого происходит откат транзакции 1. В результате значение, полученное второй транзакцией, будет отличаться от реального значения, хранимого в базе данных.

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

Транзакция 1

Транзакция 2

SELECT cost FROM ShopTable

WHERE id_product = 1;

UPDATE ShopTable SET cost=cost*2

WHERE id_product = 1;

SELECT cost FROM ShopTable

WHERE id_product = 1;

SELECT cost FROM ShopTable

WHERE id_product = 1;

В транзакции 2 выбирается значение поля cost, затем транзакция 1 изменяет значение этого поля. При повторной попытке выбора значения из поля cost в транзакции 2 будет получен другой результат. Пример: данные о стоимости продуктов считываются из таблицы ShopTable, на их основе строится статистика и сохраняется в таблице StatTable. При повторном чтении данные не совпадают, следовательно таблица StatTable будет содержать ошибку.

  1. Фантомная вставка – частный случай неповторяющегося чтения – заключается в том, что результаты одной и той же выборки в рамках одной транзакции имеют разное количество возвращаемых строк.

Транзакция 1

Транзакция 2

INSERT ShopTable (pr_name, cost)

VALUES (rake, 1000);

SELECT AVG(cost) FROM ShopTable;

SELECT AVG(cost) FROM ShopTable;

В транзакции 2 выполняется запрос, использующий все значения поля cost. Затем транзакция 1 выполняет вставку новой строки, после этого повторное выполнение запроса в транзакции 2 выдаст другой результат.

При этом, если выполняемый запрос выбирает не все значения поля cost, а значение только одной строки таблицы, то выполнение оператора INSERT не приведет к ситуации фантомной вставки.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]