Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГОСы - ответы (КБ-61).docx
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
3.51 Mб
Скачать

43. Транзакции. Свойства acid транзакций. Управление параллельностью. Блокировки. Строгий протокол двухфазной блокировки.

Под транзакцией понимается неделимая с точки зрения воздействия на БД последовательность операторов манипулирования данными (чтения, удаления, вставки, модификации), приводящая к одному из двух возможных результатов: либо последовательность выполняется, если все операторы правильные, либо вся транзакция откатывается, если хотя бы один оператор не может быть успешно выполнен. Обработка транзакций гарантирует целостность информации в базе данных. Таким образом, транзакция переводит базу данных из одного целостного состояния в другое.

Одним из наиболее распространённых наборов требований к транзакциям и транзакционным системам является набор ACID. ACID  - атомарность, согласованность, изолированность, долговечность - описывает требования к транзакционной системе (например, к СУБД), обеспечивающие наиболее надёжную и предсказуемую её работу.

- Атомарность гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. Поскольку на практике невозможно одновременно и атомарно выполнить всю последовательность операций внутри транзакции, вводится понятие «отката» (rollback): если транзакцию не удаётся полностью завершить, результаты всех её до сих пор произведённых действий будут отменены и система вернётся в исходное состояние.

- В соответствии с требованием согласованности, система находится в согласованном состоянии до начала транзакции и должна остаться в согласованном состоянии после завершения транзакции.

- Требование долговечности: независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. Другими словами, если пользователь получил подтверждение от системы, что транзакция выполнена, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.

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

Различают последовательные (обычные), параллельные и распределённые транзакции. Термин параллельность обозначает такое свойство СУБД, которое, как правило, позволяет одновременно обращаться с помощью многих транзакций к одной и той же базе данных. Очевидно, что в системе, обладающей таким свойством, требуется определенный механизм управления, который позволяет добиться того, чтобы параллельно выполняемые транзакции не нарушали работу друг друга.

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

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

  • «грязное» чтение (dirty read) — чтение данных, которые были записаны откатанной транзакцией;

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

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

Рассмотрим ситуации, в которых возможно возникновение данных проблем. Предположим, имеется две транзакции, открытые различными приложениями, в которых выполнены некоторые SQL-операторы.

Потерянное обновление

Транзакция 1

Транзакция 2

SELECT f2 FROM tbl1 WHERE f1=1;

SELECT f2 FROM tbl1 WHERE f1=1;

UPDATE tbl1 SET f2=20 WHERE f1=1;

UPDATE tbl1 SET f2=25 WHERE f1=1;

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

«Грязное» чтение

Транзакция 1

Транзакция 2

SELECT f2 FROM tbl1 WHERE f1=1;

UPDATE tbl1 SET f2=f2+1 WHERE f1=1;

SELECT f2 FROM tbl1 WHERE f1=1;

ROLLBACK WORK;

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

Неповторяющееся чтение

Транзакция 1

Транзакция 2

SELECT f2 FROM tbl1 WHERE f1=1;

SELECT f2 FROM tbl1 WHERE f1=1;

UPDATE tbl1 SET f2=f2+1 WHERE f1=1;

COMMIT;

SELECT f2 FROM tbl1 WHERE f1=1;

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

Фантомная вставка

Транзакция 1

Транзакция 2

SELECT SUM(f2) FROM tbl1;

INSERT INTO tbl1 (f1,f2) VALUES (15,20);

SELECT SUM(f2) FROM tbl1;

В транзакции 2 выполняется SQL-оператор, использующий все значения поля f2. Затем в транзакции 1 выполняется вставка новой строки, приводящая к тому, что повторное выполнение SQL-оператора в транзакции 2 выдаст другой результат. Такая ситуация называется фантомной вставкой и является частным случаем неповторяющегося чтения. При этом, если выполняемый SQL-оператор выбирает не все значения поля f2, а только значение одной строки таблицы (используется предикат WHERE), то выполнение оператора INSERT не приведет к ситуации фантомной вставки.

Все описанные проблемы, могут быть устранены с помощью механизма управления параллельным выполнением, называемого блокировкой.

В его основе лежит простая идея — если для некоторой транзакции А требуется гарантия, чтобы определенный объект, в котором она заинтересована, не изменился каким-то образом без ее ведома, она приобретает блокировку на этот объект.

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

Принцип работы блокировок

  1. Прежде всего, предположим, что в системе поддерживаются блокировки двух типов: исключительные блокировки (X — exclusive) и разделяемые блокировки (S — shared). Блокировки X и S иногда именуются, соответственно, блокировками записи и блокировками чтения.

  2. Если транзакция А владеет исключительной блокировкой (X), то запрос от некоторой другой транзакции В на получение блокировки кортежа t любого типа не может быть немедленно удовлетворен.

  3. Если транзакция А владеет разделяемой блокировкой (S) кортежа t, то выполняются следующие условия:

  • запрос некоторой другой транзакции В на получение блокировки X кортежа t не может быть немедленно удовлетворен;

  • запрос некоторой другой транзакции В на получение блокировки S кортежа t может и должен быть немедленно удовлетворен (это означает, что с этого времени транзакция В также будет владеть блокировкой S кортежа).

Д анные правила можно успешно подытожить с помощью матрицы совместимости типов блокировок.

В этой матрице «N» указывает на конфликт (запрос транзакции В не может быть немедленно удовлетворен), а «Y» указывает на совместимость (запрос транзакции В может и должен быть немедленно удовлетворен). Очевидно, что эта матрица является симметричной.

Строгий протокол двухфазной блокировки

Теперь перейдем к описанию протокола блокировки, который позволяет использовать только что описанные блокировки X и S для решения возникающих проблем.

  1. Транзакция, в которой требуется выполнить выборку кортежа, должна вначале приобрести блокировку S на этот кортеж.

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

  3. Если запрос на блокировку от транзакции В не может быть немедленно удовлетворен из-за того, что он конфликтует с блокировкой, которой уже владеет транзакция А, то В переходит в состояние ожидания. Транзакция В ожидает до тех пор, пока не появится возможность удовлетворить ее запрос на блокировку, а это может произойти не раньше, чем транзакция А освободит блокировку.

Система должна обеспечить, чтобы транзакция В не ожидала до бесконечности (такая ситуация называется активным тупиком — livelock, или истощением ресурсов — starvation).

  1. Блокировки X освобождаются по завершении транзакции (COMMIT или ROLLBACK). Блокировки S также обычно освобождаются в это же время.

Возможна ситуация возникновения взаимоблокировок. Взаимоблокировка представляет собой такую ситуацию, в которой две или несколько транзакций одновременно находятся в состоянии ожидания, причем каждая из них ожидает, пока одна из остальных транзакций не освободит блокировку, чтобы получить возможность продолжить свою работу. Если произошла взаимоблокировка, желательно, чтобы система обнаружила ее и разорвала.

Для обнаружения взаимоблокировки необходимо определить наличие цикла в графе ожидания (Wait-ForGraph). Так называется граф, который, неформально выражаясь, показывает «кто кого ожидает». Чтобы разорвать взаимоблокировку, необходимо выбрать одну из транзакций, участвующих во взаимоблокировке (т.е. одну из транзакций, которые входят в состав цикла в графе ожидания), в качестве «жертвы» и выполнить ее откат, что позволяет освободить ее блокировки и дать возможность другим транзакциям продолжить свою работу.