Представления, хранимые процедуры, триггеры Управление БД в СУБД
Понятие транзакции. Модели транзакций
Транза́кция (англ. transaction) — в информатике, группа последовательных операций, которая представляет собой логическую единицу работы с данными. Транзакция может быть выполнена либо целиком и успешно, соблюдая целостность данных и независимо от параллельно идущих других транзакций, либо не выполнена вообще и тогда она не должна произвести никакого эффекта. Транзакции обрабатываются транзакционными системами, в процессе работы которых создаётся история транзакций.
Различают последовательные (обычные), параллельные и распределённые транзакции. Распределённые транзакции подразумевают использование больше чем одной транзакционной системы и требуют намного более сложной логики (например, two-phase commit — двухфазный протокол фиксации транзакции). Также, в некоторых системах реализованы автономные транзакции, или подтранзакции, которые являются автономной частью родительской транзакции.
Пример транзакции
Пример: Необходимо перевести с банковского счёта номер 5 на счёт номер 7 сумму в 10 денежных единиц. Этого можно достичь, к примеру, приведённой последовательностью действий:
- Начать транзакцию;
- прочесть баланс на счету номер 5;
- уменьшить баланс на 10 денежных единиц;
- сохранить новый баланс счёта номер 5;
- прочесть баланс на счету номер 7;
- увеличить баланс на 10 денежных единиц;
- сохранить новый баланс счёта номер 7;
- Окончить транзакцию.
Эти действия представляют собой логическую единицу работы «перевод суммы между счетами», и таким образом, являются транзакцией. Если прервать данную транзакцию, к примеру, в середине, и не аннулировать все изменения, легко оставить владельца счёта номер 5 без 10 единиц, тогда как владелец счета номер 7 их не получит.
В идеале транзакции разных пользователей должны выполняться так, чтобы создавалась иллюзия, что пользователь текущей транзакции — единственный. Однако в реальности, по соображениям производительности и для выполнения некоторых специальных задач, СУБД предоставляют различные уровни изоляции транзакций. Уровни описаны в порядке увеличения изоляции транзакций и надёжности работы с данными
0 — Неподтверждённое чтение (Read Uncommitted, Dirty Read, грязное чтение) — чтение незафиксированных изменений своей транзакции и конкурирующих транзакций, возможны нечистые, неповторяемые чтения и фантомы
1 — Подтверждённое чтение (Read Committed) — чтение всех изменений своей транзакции и зафиксированных изменений конкурирующих транзакций, нечистые чтения невозможны, возможны неповторяемые чтения и фантомы
2 — Повторяемое чтение (Repeatable Read, Snapshot) — чтение всех изменений своей транзакции, любые изменения, внесённые конкурирующими транзакциями после начала своей, недоступны, нечистые и неповторяемые чтения невозможны, возможны фантомы
3 — Упорядоченный — (Serializable, сериализуемый) — упорядоченные (сериализуемые) транзакции. Идентичен ситуации, при которой транзакции выполняются строго последовательно, одна после другой. То есть транзакции, результат действия которых не зависит от порядка выполнения шагов транзакции (запрещено чтение всех данных, изменённых с начала транзакции, в том числе и своей транзакцией). Фантомы невозможны.
Чем выше уровень изоляции, тем больше требуется ресурсов, чтобы их поддерживать.
В СУБД уровень изоляции транзакций можно выбрать как для всех транзакций сразу, так и для одной конкретной транзакции. По умолчанию в большинстве баз данных используется уровень 1 (Read Committed). Уровень 0 используется в основном для отслеживания изменений длительных транзакций или для чтения редко изменяемых данных. Уровни 2 и 3 используются при повышенных требованиях к изолированности транзакций.
Реализация
Необходимо выполнять требования ACID, которые описывают требования к транзакционной системе (например, к СУБД), обеспечивающие наиболее надёжную и предсказуемую её работу.
Обработка поступающих данных приводит к большому количеству маленьких изменений, включая обновление как самих таблиц, так и индексов. Эти изменения потенциально могут потерпеть неудачу: закончилось место на диске, операция занимает слишком много времени (timeout) и т. д. Система должна в случае неудачи корректно вернуть базу данных в состояние до транзакции.
Первые коммерческие СУБД (к примеру, IBM DB2), пользовались исключительно блокировкой доступа к данным для обеспечения свойств ACID. Но большое количество блокировок приводит к существенному уменьшению производительности. Есть два популярных семейства решений этой проблемы, которые снижают количество блокировок:
- Журнализация изменений (write ahead logging, WAL)
- механизм теневых страниц (shadow paging).
В обоих случаях, блокировки должны быть расставлены на всю информацию, которая обновляется. В зависимости от уровня изоляции и имплементации, блокировки записи также расставляются на информацию, которая была прочитана транзакцией.
При упреждающей журнализации, используемой в Sybase и MS SQL Server до версии 2005, все изменения записываются в журнал, и только после успешного завершения - в базу данных. Это позволяет СУБД вернуться в рабочее состояние после неожиданного падения системы. Теневые страницы содержат копии тех страниц базы данных на начало транзакции, в которых происходят изменения. Эти копии активизируются после успешного завершения. Хотя теневые страницы легче реализуются, упреждающая журнализация более эффективна.
Дальнейшее развитие технологий управления базами данных привело к появлению безблокировочных технологий. Идея контроля за параллельным доступом с помощью временных меток (timestamp-based concurrency control) была развита и привела к появлению многоверсионной архитектуры MVCC. Эти технологии не нуждаются ни в журнализации изменений, ни в теневых страницах. Архитектура, реализованная в Oracle 7.х и выше, записывает старые версии страниц в специальный сегмент отката, но они все ещё доступны для чтения. Если транзакция при чтении попадает на страницу, временная метка которой новее начала чтения, данные берутся из сегмента отката (то есть используется «старая» версия). Для поддержки такой работы ведётся журнал транзакций, но в отличие от «упреждающей журнализации», он не содержит данных. Работа с ним состоит из трёх логических шагов:
- Записать намерение произвести некоторые операции;
- Выполнить задание, копируя оригиналы изменяемых страниц в сегмент отката;
- Записать, что всё сделано без ошибок.
Журнал транзакций в сочетании с сегментом отката (область, в которой хранится копия всех изменяемых в ходе транзакции данных) гарантирует целостность данных. В случае сбоя запускается процедура восстановления, которая просматривает отдельные его записи следующим образом:
Если повреждена запись, то сбой произошёл во время проставления отметки в журнале. Значит, ничего важного не потерялось, игнорируем эту ошибку.
Если все записи помечены как успешно выполненные, то сбой произошёл между транзакциями, здесь также нет потерь.
Если в журнале есть незавершённая транзакция, то сбой произошёл во время записи на диск. В этом случае мы восстанавливаем старую версию данных из сегмента отката.
Firebird вообще не имеет ни журнала изменений, ни сегмента отката, а реализует MVCC, записывая новые версии строк таблиц прямо в активное пространство данных. Также поступает MS SQL 2005. Теоретически это даёт максимальную эффективность при параллельной работе с данными, но ценой является необходимость «сборки мусора», то есть удаления старых и уже не нужных версий данных.
Итак, транзакции позволяют объединить в одну группу несколько SQL операторов и интерпретировать их как один составной оператор. В этой группе будут выполнены либо все операторы, либо ни один из них не будет выполнен.
SQL Сервер автоматически выполняет все операторы модификации данных, включая одношаговые изменения, как транзакции. По умолчанию каждый оператор вставки, обновления и удаления выполняется как простая транзакция.
Пользователь может сгруппировать множество SQL операторов в транзакцию с помощью команд begin transaction (начать транзакцию), commit transaction (подтвердить транзакцию), rollback transaction (откатить транзакцию). Команда begin transaction отмечает начало транзакции. Все остальные операторы вплоть до оператора rollback transaction или соответствующего оператора commit transaction включаются в эту транзакцию.
Транзакции позволяют гарантировать следующие свойства:
· Корректность - Одновременные запросы и изменения данных не противоречат друг другу и пользователь никогда не видит и не работает с данными, которые являются только частью некоторого изменения;
· Восстанавливаемость - В случае системного сбоя база данных полностью автоматически восстанавливается.
Для поддержки транзакций, удовлетворяющих SQL стандарту, SQL Сервер предоставляет опции, которые позволяют выбрать режим и уровень изоляции (isolation level) транзакции. В приложениях, где используются транзакции, удовлетворяющие стандарту, необходимо устанавливать эти опции в начале каждой сессии. Режимы транзакций и уровни изоляции обсуждается далее в этой главе.
В многопользовательской среде SQL Сервер должен предотвращать одновременные запросы и попытки одновременного изменения данных со стороны различных пользователей. Это очень важно, поскольку в противном случае данные, обрабатываемые одним запросом, могут быть модифицированы другим пользователем, что может привести к противоречивому результату.
SQL Сервер автоматически устанавливает соответствующий уровень блокировки для каждой транзакции. Можно установить более сильную разделяемую блокировку (shared locks) для поочередных запросов, указав ключевое слово holdlock в операторе выбора select.
Пользователь может определить транзакцию, указать SQL Серверу, что последовательность SQL операторов нужно выполнить как единый блок. Эта возможность обсуждается далее в этой главе.
Транзакции являются как единицей работы, так и единицей восстановления данных. Тот факт, что SQL Сервер выполняет одношаговые (простые) запросы как транзакции означает, что база данных может быть полностью восстановлена в случае возникновения ошибок.
Время восстановления измеряется в секундах и минутах. Можно указать максимально допустимое время восстановления.
SQL операторы, связанные с восстановлением и отменой изменения данных, обсуждаются в разделе «Отмена и восстановление транзакций».
Модели транзакций
Рассмотрим две модели транзакций, используемые в большинстве коммерческих СУБД:
- модель автоматического выполнения транзакций;
- модель управляемого выполнения транзакций, обе основаны на инструкциях языка SQL – COMMIT и ROLLBACK.
Автоматическое выполнение транзакций.
В стандарте ANSI/ISO зафиксировано, что транзакция автоматически начинается с выполнения пользователем или программой первой инструкции SQL. Далее происходит последовательное выполнение инструкций до тех пор, пока транзакция не завершается одним из двух способов:
• инструкцией COMMIT, которая выполняет завершение транзакции: изменения, внесенные в БД, становятся постоянными, а новая транзакция начинается сразу после инструкции COMMIT;
• инструкцией ROLLBACK, которая отменяет выполнение текущей транзакции и возвращает БД к состоянию начала транзакции, новая транзакция начинается сразу после инструкции ROLLBACK.
Такая модель создана на основе модели, принятой в СУБД DB2.
Управляемое выполнение транзакций.
Отличная от модели ANSI/ISO модель транзакций используется в СУБД Sybase, где применяется диалект Transact-SQL, в котором для обработки транзакций служат четыре инструкции:
• инструкция BEGIN TRANSACTION сообщает о начале транзакции, т.е. начало транзакции задается явно;
• инструкция COMMIT TRANSACTION сообщает об успешном выполнении транзакции, но при этом новая транзакция не начинается автоматически;
• инструкция SAVE TRANSACTION позволяет создать внутри транзакции точку сохранения и присвоить сохраненному состоянию имя точки сохранения, указанное в инструкции;
• инструкция ROLLBACK отменяет выполнение текущей транзакции и возвращает БД к состоянию, где была выполнена инструкция SAVE TRANSACTION (если в инструкции указана точка сохранения – ROLLBACK TO имя_точки_сохранения), или к состоянию начала транзакции.
Управление обработкой.
Представления, хранимые процедуры, триггеры
Для решения типовых (часто, повторяющихся) задач выборки или обновления данных, а также в значительной части для управления доступом к данным (как альтернатива механизму разрешения — запрета) и обеспечения целостности данных целесообразно использовать процедуры. Кроме того, другое преимущество, уже в части администрирования, состоит в том, что не надо специально определять пользователю права доступа к таблицам и представлениям, используемым в процедуре: достаточно определить только разрешение на выполнение процедуры.
Существуют два способа взаимодействия приложения с SQL Server. Можно создать приложение, отправляющее клиентские операторы T-SQL на сервер, либо создать хранимые процедуры непосредственно на сервере. В первом случае операторы каждый раз рекомпилируются сервером. Второй способ активизирует хранимые процедуры, вызывая их из приложения одним оператором. При первом вызове хранимой процедуры она компилируется и создается план ее выполнения, который сохраняется в памяти. При последующих вызовах SQL Server будет использовать этот план и процедуру повторно не компилирует. Таким образом, когда для решения определенных задач требуется многократно выполнить одну и ту же последовательность операторов SQL, применение хранимой процедуры обеспечивает более высокую производительность.
Для управления обработкой в процедурах можно использовать локальные переменные, которые создаются с помощью оператора DECLARE. Переменная доступна с момента ее объявления и до выхода из процедуры. После выхода из процедуры на переменную ссылаться нельзя. Локальные переменные можно объявлять в пакете, в сценарии, внешней программе, а также в хранимой процедуре. В операторе DECLARE необходимо указать имя переменной и ее тип.
Представления (просмотры)
Это заранее составленный и хранящийся БД SQL- запрос для выборки данных из одной или нескольких таблиц БД( просмотр в момент создания оптимизируется и компилируется сервером, что сокращает время выполнения запроса).
Представления (View)существуют независимо от информации в базе данных, но тесно с ней связаны. Представления используются для фильтрования и предварительной обработки данных.
Представление - это по существу некая виртуальная таблица(составленная средствами запроса SELECT из нужных столбцов, возможно разных таблиц ии запросаются сервером таким образом, чтобы в максимальной степени ггерами и другими ее компонентами.), содержащая результаты выполнения запроса (оператора SELECT) к одной или нескольким таблицам. Для конечного пользователя представление выглядит как обычная таблица в базе данных, над которой можно выполнять операторы SELECT, INSERT, UPDATE и DELETE. В действительности представление хранится в виде предопределенного оператора SQL. Подобно хранимым процедурам запрос SELECT просмотра автоматически автоматизируется сервером, что позволяет выполнить его за минимально возможное время.
Типы представлений.Различные типы представлений имеют свои преимущества и недостатки. Выбор того или иного типа представлений полностью зависит от задач приложения. Выделяют следующие типы представлений:
• подмножество полей таблицы — состоит из одного или более полей таблицы и считается самым простым типом представления. Обычно используется для упрощения представления данных и обеспечения безопасности;
• подмножество записей таблицы — включает определенное количество записей таблицы и также применяется для обеспечения безопасности;
• соединение двух и более таблиц — создается соединением нескольких таблиц и используется для упрощения сложных операций соединения;
• агрегирование информации — создается группированием данных и также применяется для упрощения сложных опе раций. »
Представления также позволяют логически объединять данные. Например, если данные хранятся в нескольких таблицах, их затем посредством представления можно объединить в более крупную виртуальную таблицу.
Еще одно преимущество представлений заключается в том, что они могут иметь более низкий уровень безопасности, чем их исходные таблицы. Запрос для представления выполняется согласно уровню безопасности вызывающего его пользователя. Таким образом, представление можно применять для сокрытия данных от определенной группы пользователей.
Представления, как и индексы, можно создавать различными способами: использовать для этого «мастер» или команду T-SQL, имеющую в общем случае следующий формат.
CREATE VIEWимя представления [столбец[,..]]
AS SELECT - onepamop
Следует отметить, что использование в операторе SELECT предложения WHERE позволяет локализовать доступ пользователя к данным даже на уровне отдельных строк и столбцов.
Удаление представлений выполняется с помощью оператор DROP VIEW, при вызове которого могут указываться параметры RESTRICT или CASCADE. Данные параметры определяют действия при удалении представления, на которое ссылаются другие представления и/или ограничения.
Типовой синтаксис оператор DROP VIEW имеет следующий вид:
DROP VIEW имя_представления [RESTRICT | CASCADE]
Представления в основном применяются в двух случаях:
· с целью защиты данных;
· для формирования итоговых данных.
Представления могут быть использованы для ограничения доступа не только к полям, но и к записям таблицы. Для этого достаточно в запросе на выборку данных, на основе которого создается представление, указать соответствующее ограничительное условие. Например, в рассмотренном выше примере с работниками отдела кадров можно при создании представления задать условие, которое будет исключать из представления сотрудников, занимающих определенные должности.
Хранимые процедуры
Это программа (процедура) обработки данных, хранящаяся и выполняемая на компьютере- сервере(в базе данных).
Хранимые процедуры - это часто используемые клиентом SQL- запросы, оформленные надлежащим образом и хранимые в БД вместе таблицами, индексами, триггерами и другими ее компонентами.Хранимые процедуры обязательно оптимизируются сервером таким образом, чтобы в максимальной степени сократить время реализации запроса. Это программа (процедура) обработки данных, хранящаяся и выполняемая на компьютере- сервере(в базе данных).
Хранимая процедура (stored procedure)— это набор операторов T-SQL, которые SQL SERVER компилирует в единый план выполнения. Этот план сохраняется в кэше процедур при первом выполнении хранимой процедуры, и затем план можно повторно использовать уже без рекомпиляции при каждом вызове. Хранимая процедура аналогична процедурам в языках программирования: она может принимать входные параметры, возвращать данные и коды завершения.
Применение хранимых процедур улучшает производительность, например, при использовании в хранимой процедуре условных операторов (таких как IF и WHILE), поскольку условие будет проверяться непосредственно на сервере и серверу не потребуется возвращать промежуточные результаты проверки условия программам-клиентам.
Хранимые процедуры также позволяют централизованно контролировать выполнение задачи, что гарантирует соблюдение бизнес-правил.
Хранимые процедуры, как и представления, можно создавать различными способами: использовать для этого «мастер» или команду T-SQL, имеющую в общем случае следующий формат
CREATE PROCEDURE имяпроцедуры [(%параметр1 тип_данных[,..]] AS SQL-операторы
Существует два типа хранимых процедур: системные и пользовательские. Первые поддерживается SQL Server и применяются для управления сервером и отображения информации о базах данных и пользователях. Вторые создаются пользователями для выполнения прикладных задач.
Процедуры выбора выполняются при обращении к ним с помощью оператора выборки данных SELECT. Для вызова выполняемой процедуры следует использовать специальный оператор EXECUTE. Синтаксис этого оператора зависит от используемой реализации SQL.
Для удаления хранимых процедур используется оператор DROP PROCEDURE. Синтаксис этого оператора является достаточно общим для различных реализаций SQL и имеет следующий вид:
DROP PROCEDURE имя_хранимой_процедуры
Триггеры
Триггер (trigger) — это особый тип хранимой процедуры, которая автоматически выполняется при изменении таблицы с помощью операторов UPDATE, INSERT или DELETE. Как и хранимые процедуры, триггеры содержат операторы T-SQL, но в отличие от процедур запускаются не индивидуально, а автоматически при выполнении операций изменения данных. Триггеры наряду с ограничениями обеспечивают целостность данных и соблюдение бизнес-правил, однако их следует использовать разумно. Например, не нужно создавать триггер, проверяющий наличие значения первичного ключа в одной таблице, чтобы определить, можно ли вставить значение в соответствующее поле другой таблицы. Однако трудно обойтись без триггеров при выполнении каскадных изменений в дочерних таблицах.
Триггер создается на одной таблице в текущей базе данных, хотя может использовать данные других таблиц и объекты других баз данных. Триггеры нельзя создавать на представлениях, временных и системных таблицах. Таблица, для которой определен триггер, называется таблицей триггера.
Существуют три типа триггеров: UPDATE, INSERT и DELETE, каждый из которых инициируется при выполнении одноименной команды. Операции UPDATE, INSERT и DELETE иногда называют событиями изменения данных. Можно создать триггер, который будет срабатывать при возникновении более чем одного события, например, запускаться в ответ на операторы UPDATE или INSERT. Такие комбинированные триггеры называются UPDATE/INSERT. Возможно создание триггеров, срабатывающих при выполнении любого из трех операторов обновления данных (триггер UPDATE/ INSERT/DELETE).
Триггеры, как и представления, можно создавать различными способами: использовать для этого «мастер» или команду T-SQL, имеющую в общем случае следующий формат:
CREATE TRIGGER имя_триггера
ON ■имя таблицы
FOR [INSERT] [,] [UPDATE] [,] [DELETE]
AS SQL-операторы
В программе-триггере нельзя использовать операторы создания, реструктуризации, удаления объектов, реконфигурации и восстановления.
Работа триггеров подчиняется следующим правилам:
• триггеры запускаются только после завершения выполнения вызывающего их оператора. Например, триггер UPDATE не начинает работать, пока не завершится выполнение оператора UPDATE;
• триггер не начинает работать, если при выполнении оператора происходит нарушение какого-либо ограничения таблицы или возникает другая ошибка;
• триггер и вызывающий его оператор образуют транзакцию. В результате вызова из триггера оператора ROLLBACK отменяются изменения, выполненные триггером и оператором. При возникновении серьезной ошибки, например, при отключении пользователя, SQL-Server автоматически выполнит откат всей транзакции;
• триггер запускается один раз для каждого оператора, независимо от количества изменяемых оператором записей.
Триггеры возвращают результаты своей работы в приложение, подобно хранимым процедурам. Как правило, пользователь не ожидает вывода после выполнения операторов UPDATE, INSERT и DELETE, вызывающих срабатывание триггеров. Если триггер возвращает данные, приложение должно содержать код, правильно интерпретирующий результаты модификации таблицы и вывод триггера.
Для каждого триггера SQL Server создает две временные таблицы, на которые можно ссылаться в описании триггера. Эти таблицы хранятся в памяти и локальны по отношению к триггеру, то есть триггер имеет доступ только к своей собственной версии таблиц. Временные таблицы применяются для сравнения состояния таблицы до и после внесения изменений.
В MS SQL Server возможно создание нескольких триггеров на таблице для каждого события изменения данных (UPDATE, INSERT или DELETE) и рекурсивный вызов триггера. Например, если для таблицы уже определен триггер UPDATE, то можно определить еще один триггер UPDATE для той же самой таблицы. В этом случае после выполнения соответствующего оператора сработают оба триггера. Кроме того, допускаются вложенные триггеры, которые срабатывают в результате выполнения других триггеров. Они отличаются от рекурсивных тем, что не запускают сами себя.
Для удаления триггера используется оператор DROP TRIGGER.
Синтаксис выглядит так: DROP TRIGGER имя_триггера
Так же как и хранимые процедуры, триггеры состоят из заголовка и тела. Заголовок триггера содержит:
- имя триггера, уникальное внутри базы данных;
- имя таблицы, с которой связан триггер;
- инструкции, которые определяют когда триггер будет выполняться;
Тело триггера содержит:
- список локальных переменных и их типов данных;
- блок инструкций на языке процедур и триггеров, заключенный между ключевыми словами BEGIN и END.
Таким образом, отличие триггера от хранимой процедуры заключается только в заголовке.
Репликация
Репликация- существование нескольких копий одного и того же файла, каждая из которых хранится на отдельном сервере(ПК), при этом обеспечивается автоматическое согласование данных в копиях файла.
Репликация базы данных заключается в копировании, или тиражировании, данных из одной таблицы или базы данных в другую.
Офис с сетью региональных отделений — показательный случай для использования системы с репликацией транзакций. Каждый филиал ведет работу со своими счетами, информация о которых содержится в его базе данных. Главный офис является подписчиком на базы данных всех филиалов, что позволяет собирать в нем информацию по всей организации.
Репликация основана на метафоре «издатель — подписчик»: издатель (публикующий сервер) предоставляет данные; распространитель содержит тиражируемую базу или служебную информацию для управления репликацией; подписчик — получает и обрабатывает реплицированные данные. Данные передаются от публикующего или рассылающего сервера в направлении каждого из подписчиков. Данные не могут пересылаться подписчику непосредственно от другого подписчика. Если один из подписчиков перестает функционировать, это не должно оказывать никакого влияния на издателя или других подписчиков.
В схеме репликации транзакций для доставки данных от публикующего сервера на каждый из серверов-подписчиков используются три следующих компонента:
• агент синхронизации (Snapshot Agent). Создает файлы данных и структуры, используемые для согласования новых подписчиков с текущим состоянием публикации;
• агент чтения журнала (Log Reader Agent). Считывает из журнала транзакций публикующего сервера подлежащие репликации транзакции и помещает их в базу данных рассылки;
• агент рассылки (Distributation Agent). Пересылает подлежащие репликации транзакции из базы данных рассылки всем подписчикам на публикацию.
Каждая публикация (набор реплицируемых данных — статей, которыми могут быть таблицы, записи, поля или хранимые процедуры) создается для выделения данных, подлежащих репликации в базе данных подписчиков. Агент синхронизации создает файл схемы, предназначенный для создания в базе данных табличных структур реплицируемых данных. Этот агент также создает файлы, содержащие данные из публикуемых статей, и обновляет содержимое базы данных рассылки для фиксации нового задания на согласование.
В журнале транзакций публикующего сервера все транзакции, подлежащие репликации в адрес одного или более подписчиков, помечаются специальным флажком. Агент чтения журнала считывает из журнала все помеченные этим флажком команды INSERT, UPDATE и DELETE. Агент следит за появлением подлежащих репликации транзакций для каждой публикации, существующей в базе данных публикующего сервера. Любая обнаруженная транзакция копируется им в базу данных рассылки. Затем агент чтения журналов адресует рассылаемые данные каждому подписчику на публикацию.
После исходного согласования состояний подписчика и публикующего сервера весь объем данных никогда не пересылается в адрес подписчика. Поддержание актуального состояния базы данных подписчика обеспечивается агентом рассылки. Он пересылает подписчику все команды INSERT, UPDATE и DELETE, введенные пользователями на стороне публикующего сервера. Очень важно четко представлять всю последовательность действий, которые выполняются при передаче подписчику сведений об изменениях, проведенных на стороне публикующего сервера.
При создании публикации разработчик может разрешить подписчику выполнять обновление собственной локальной копии данных. В этом случае все выполненные на стороне такого подписчика изменения будут переданы в обратном направлении на публикующий сервер, а последний разошлет их в адрес всех остальных серверов-подписчиков. Отсутствие конфликтов и гарантия внесения изменений на публикующий сервер обеспечиваются благодаря использованию на сервере-подписчике протокола двухступенчатой фиксации изменений. Если публикующий сервер по какой-либо причине не сможет получить сведения о внесенных изменениях, выполненная на стороне подписчика транзакция будет отменена и восстановится исходное состояние базы данных. В такой схеме непосредственно обновляемых подписчиков используются триггеры, хранимые процедуры, координатор распределенных транзакций, а также средства обнаружения конфликтов и рекурсии.
Триггеры размещаются на стороне подписчика. Это гарантирует, что любая начатая на сервере-подписчике транзакция будет обязательно зафиксирована на публикующем сервере, прежде чем появится возможность зафиксировать ее на сервере-подписчике. Здесь используется протокол с двухступенчатой фиксацией изменений (Two Phase Commit — 2РС). Если транзакцию не удастся зафиксировать на публикующем сервере, она будет отменена и на сервере-подписчике, поэтому состояние обеих баз данных останется согласованным.
Хранимые процедуры размещаются на стороне публикующего сервера. Это гарантирует, что любые реплицируемые транзакции будут выполнены только в том случае, если это не приведет к конфликту. Если в результате выполнения транзакции возникает конфликт, на серверах обоих узлов для данной транзакции будет выполнен откат.
Координацию выполнения двухступенчатой фиксации изменений между публикующим сервером и сервером-подписчиком осуществляет Координатор распределенных транзакций (Microsoft Distributed Transaction Coordinator — MS DTC), который вызывает выполнение удаленных хранимых процедур.
|