![]() |
|
Программирование >> Реляционные базы данных
7-2.2 Атомарность Несмотря иа то что две и более операций на БД могут выполняться почти одновременно, единственная операция способна привести БД в неприемлемое состояние при сбое программного или аппаратного обеспечения во время выполнения операции. Приведем пример того, что может при этом произойти Следует помнить, что такого рода ошибки не случаются в правильно построенных прикладных программах. Пример 7.12, Рассмотрим широко распространенный тип БД - записи банковских счетов. Эти записи предсгавлены отношением Accounts с атрибутами acctNo и balance. Пары этого огношения состоят из номера счета и баланса данного счета. Запишем функцию fransferO, которая читает два счета и количество денег, и, если на первом счету находится по меньшей мере такое количество, переводит деньги с первого счета на второй. Краткая запись этой функции приведена на рис 7.10. 1) EXEC SQL BEGIN DECLARE SECTION; 2) int accti, acct2; / два счета / 3) int balance 1; /* сумма денег на первом счету I 4) int amount; Г переводимая сумма денег */ 5) EXEC SQL END DECLARE SECTION; 6) void transferO { 7) /* операторы С. предлагающие пользователю ввести счета 1 и 2 и сумму переводимых денег в переменные accti acct2 и amount*/ 8) EXEC SQL SELECT balance INTO .balancel 9) FROM Accounts 10) WHERE acctNo :acct1; 11) If (balancel >= amount) { 12) EXEC SQL UPDATE Accounts 13) SET balance = balance + ramount 14) WHERE acctNo = :acct2: 15) EXEC SQL UPDATE Accounts 16) SET balance = balance-lanrount 17) WHERE acctNo = :acct1; } 18) else /* программа С ДПЯ вывода сообщения 0 TOM, что денежных средств для перевода недостаточно*/ Рлс. 7.10. Перевод денег с одного счета но другой .Эта функция действует просто. Стюкн (S) -(10) определяют баланс первого счета. Строка (Н) определяет, достаточен ли этот баланс, чтобы снять со счета нужную сумму. Если это так, то строки (Р) - (14) добавляют эту сумму ко второму счету, а строки (15) - (17) вычитают ее из первого счета. Если баланс первого счета недостаточен, перевод не выполняется и на строке (18) печатается соо1ветствуюшее предупрежден ие. Рассмотрим, что происходит в случае сбоя после строки (14): возможно, выходит из строя компьютер или прерывается по сети связь БД с процессором, выполняющим операцию. БД остается в состоянии, когда деньги переведены на второй счет, но не сняты с первого. В результате банк лишается су.ммы, которую нужно было перевести О Изменения БД в процессе транзакций \ в различных системах транзакции реализуются по-разному. Выполнение транзакции может изменять БД. После прекрашения такой транзакции изме- - нения MorjT быть видимыми аля другой транзакции. Обычное решение такой 1 проблемы - блокировка изменяемых элементов до выполнения COMMIT или [ ROLLBACK. В результате другая транзакция не может увидеть предполагаемых i изменений. Блокировки или их эквиваленты обязательно применяются тогда. когда пользователю нужно выполнять транзакции а последовательной форме. 1 Как будет показано в начале раздела 7.2.4. в SQL2 существуют рахтичиые . варианты работы п)едпоЛ!1тиемыми изменениями БД. Измененные данные \ мог>т не блокироваться и быть видимыми, лаже если последующий откат I уничтожает изменение. Разработчик транзакций сам решает, нужно ли делать г невидимыми предполагаемые изменения. Во всех реализациях SQL есть по- аобный блокировке метод сделать изменения невидимыми до их завершения. . J В некоторы\ рс:1.1:иаи11ях прнмсняютсн менее жесткие устаноики по у.мсхтаник> Проблема, показанная в примере 7.12, заключается в том, что определенные комбинаиин операций на БД типа изменений согласно рис. 7.10 должны вмпа-жять-ся атомарно, т.е. либо выполняются обе, либо не выполняется ни одна из них. Например, o6utee решение состоит в том, чтобы все изменения БД производить в локальном рабочем пространстве и фиксировать изменения БД только после ювертения работы: лишь после этого ПСС измснения станонятся частью БД и могут быть использованы н други.ч операциях. 7.2.3 транзакции Решение показанных в разделах 7.2.1 и 7.2.2 проблем преобразований последовательную форму и атомарности состоит в сведении операций на БД и тратак-ЦШ1. Транзакция - это непустое множество операций на БД. которое должно выполняться атомарно, т.е. либо выполняются все onepamiH. либо не выполняется ни одна из иих. Ранние стандарты SQL требуют также, чтобы транзакции можно было преобразовать а последовательную форму. В SQL2 используется более гибкий метод. Преобразование в последовательную форму принято в нем по умолчанию, ио пользователь может применять более мягкое ограничение относительно взаимосвязи операций из раз;гичных транзакций. Эти варианты приведения с последовательную фор.му будут рассмотрены позже. Транзакция начинается с началом работы SQL предложения, которое либо sanpaujHBaeT БД или схему, либо манипулирует ими. В SQL нет специального оператора начала транзакции, но можно явно определить ее конец двумя способа.мн. L Оператор COMMIT завершает транзакцию успешно. Любые изменения, вызванные операторо.м или операторами SQL с момента начала транзакции, постоянно вводятся в БД (т.е. принимаются). До выполнения СОММП они остаются предполагаемыми и невидимыми для других транзакций. 2. Оператор ROLLBACK вызывает прекращение транзакции, или неуспешное ее завершение. Любые изменения, выполняемые операторами SQL в рамках данной транзакции, отменяются (т.е. производится их откат], и они больиге не возникают в БД. л Транзакинм можно сравнить с упрасчением курсорами. Например, в разделе 7.1.10 говорн-пось, что курсорам, предназначенны.м только для чтения, доступен боясс г.чубоюпТ параллелизм, чем обшнм курсорам. То же са.мое относктсг II к прмиазиаченным то;1ЬКО длп чтения транзакциям. Пример 7.13. Допустим, нужно сделать выполнение функции transfer{) из примера 7.10 единой транзакцией. Она начинается на строке (S) при чтении бгшанса. первого счета. Еслн тест строки (II) дает положительный результат н пь нолняется перевод денег, такое изменение желательно зафиксировать. Для этого в конце ir-блока строк il2j -(17) вводится дополнительный оператор SQL: EXEC SQL COMMIT; Еслн тест строки (II) дает отрицательный результат, т.е. средств для перевода недостаточно, транзакцию нужно аннулировать, введя оператор EXEC SQL ROLLBACK; в конце else-блока на строке (18). Поскольку в этом случае не выполняется никакой оператор изменения БД, фиксация и удэ-пение не играют роли, поскольку нет изменений, которые нужно принять. □ 7.2.4 Транзакции, предназначенные только для чтения в примерах 7.11 и 7.12 приведены транзакции, которые считывают, а затем (возможно) записывают данные в БД. Такой тип транзакций связан с пробле.мой преобразования в последовательную форму. В примере 7.11 показано, что происходит, когда два выполнения функции направлены на резервирование одного и того же места в одно и то же время. В примере 7.12 показано, что случается при сбое в процессе выполнения функции. Если же транзакция только считывает данные и не записывает их, существуют более широкие возможности для ее выполЕ1ення параллельно с другими транзакциями. Пример 7.14. Допустим, написана функшня, считывающая данные и определяющая, свободно ли конкретное место авиарейса. Она действует согласно строкам (I) -(И) на рис. 7.8. Можно выполнить одновременно несколько вызовов такой функции без всякого риска повредить БД. Наихудшее, что может случиться,- это то. что во время определения лослпности конкретного места оно резервируется илн освобождается в результате выполнения другой функции. Значит, ответ свсодно или занято может зависеть от микроскопической разницы во времени вь!Полнения запроса, в определенный момент ответ все равно будет иметь смысл. □ Еслн сообщить исполнительной системе SQL о том, что текущая транзакция предназначена только для чтения, т.е. никогда не изменяет БД, вполне возможно, что система извлечет пользу из этого знания. Не вдаваясь в подробности, отметим, что многие предназначенные только для чтения транзакции, использующие одни и те же данные, могут выполняться параллельно, что невозможно для транзакций, записывающих данные. Сообщить системе SQL о том. что следующая транзакция предназначена только лля чтения, можно с помоилью оператора SET TRANSACTION READ ONLY; который должен выполняться до начала транзакции. Например, функцию, выраженную строками (!) -(II) на рис. 7,8, можно объявить предназначенной только для чтения, поместив EXEC SQL SET TRANSACTION READ ONLY;
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |