DeepEdit!

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

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

Распределенные транзакции

Одним из действительно замечательных свойств СУБД Oracle является ее спо­собность прозрачно обрабатывать распределенные транзакции. Я могу обновить данные во множестве разных баз данных за одну транзакцию. Когда я выполняю ее фиксацию, то либо фиксируются все обновления во всех экземплярах, либо не фиксируется ни одно из них (все они откатываются). Мне не нужен для этого ни­какой дополнительный код; я просто пишу commit;. 
Ключом к распределенным транзакциям в Oracle является связь баз данных (database link). Эта связь представляет собой объект базы данных, описывающий способ регистрации в другом экземпляре базы из вашего экземпляра. Однако цель настоящего раздела не в том, чтобы раскрыть синтаксис команд связи баз данных (он полностью документирован), а скорее просто в том, чтобы уведомить вас о его существовании. Как только вы настроите связь баз данных, доступ к удаленным объектам становится очень простым: 
select * from T@another_database; 
Это позволит выбрать данные из таблицы T в экземпляре базы данных, опреде­ленном связью ANOTHER_DATABASE. Обычно вы должны “скрывать” тот факт, что T— удаленная таблица, создавая ее представление или синоним. Например, мож­но выполнить следующую команду и затем обращаться к T, как если бы это была локальная таблица: 
create synonym T for T@another_database; 
Теперь, имея настроенную связь с удаленной базой и получив возможность чи­тать некоторые таблицы, я также могу модифицировать их (конечно, при условии обладания соответствующими привилегиями). Выполнение распределенной тран­закции теперь ничем не отличается от транзакции локальной. Вот все, что для это­го нужно: 
update local_table set x = 5;
update remote_table@another_database set y = 10;
commit; 
Вот и все. СУБД Oracle выполнит фиксацию либо в обеих базах данных, либо ни в одной из них. Она использует протокол 2PC (двухфазной фиксации). Этот про­токол позволяет выполнять модификации, затрагивающие множество различных баз данных, фиксируя их автоматически. Он, насколько возможно, пытается пере­крыть все пути для распределенных сбоев перед тем, как выполнить фиксацию. В 2PC между многими базами данных одна из баз — обычно та, к которой клиент подключился изначально — служит координатором распределенной транзакции. Этот сайт запросит у других сайтов готовности к фиксации. То есть этот сайт обра­тится к другим сайтам и попросит их подготовиться к фиксации. Каждый из этих других сайтов рапортует о своем “состоянии готовности”, как “ДА” или “НЕТ”. Если любой из сайтов говорит “НЕТ”, выполняется откат всей транзакции. Если же все сайты рапортуют “ДА”, сайт-координатор рассылает сообщение с командой на вы­полнение фиксации на всех сайтах. 
Это ограничивает возможности для серьезных ошибок. Прежде чем выполнит­ся “опрос” по 2PC, любая распределенная ошибка приведет к выполнению отката на всех сайтах. Не будет никаких сомнений относительно исхода распределенной транзакции. После команды на фиксацию или откат опять-таки нет никаких со­мнений относительно исхода распределенной транзакции. Лишь в течение очень короткого периода (“окна”) времени, когда координатор собирает ответы, исход мо­жет быть неоднозначным после сбоя. 
Предположим, например, что у нас есть три сайта, участвующих в транзак­ции. Сайт 1 выступает в роли координатора. Сайт 1 просит сайт 2 подготовиться к фиксации, и сайт 2 выполняет это. Затем сайт 1 просить сайт 3 подготовиться к фиксации, и он также делает это. В этот момент времени сайт 1 — единственный, кто знает об исходе транзакции, и теперь он отвечает за извещение об этом других сайтов. Если ошибка случится прямо сейчас — произойдет сбой сети, сайт 1 оста­нется без питания или еще что-то — сайты 2 и 3 останутся в “подвешенном” состо­янии. Они получат то, что называется сомнительной распределенной транзакци­ей. Протокол 2PC пытается закрыть “окно” ошибок, насколько это возможно, но не может исключить такую вероятность полностью. Сайты 2 и 3 должны удерживать транзакцию открытой, ожидая нотификации от сайта 1 команды на фиксацию или откат. Если вы помните дискуссию об архитектуре из главы 5, там было сказано, 
что для разрешения этой проблемы существует процесс RECO. Это также тот слу­чай, когда на сцену выходят COMMIT и ROLLBACK с опцией FORCE. Если причиной проблемы был сбой сети между сайтами 1, 2 и 3, то администраторы сайтов 2 и 3 должны обратиться к администратору сайта 1, запросить его об исходе транзакции и выполнить, соответственно, фиксацию или откат вручную. Существует несколь­ко (немного) ограничений относительно того, что вы можете делать в распределен­ной транзакции, и все они оправданы (на мой взгляд, они выглядят оправданными в любом случае). Ниже перечислены наиболее существенные из них. 
Вы не можете выдать COMMIT по связи баз данных. То есть, нельзя дать ко­манду COMMIT@удаленный_сайт. Вы можете зафиксировать транзакцию толь­ко на сайте, который ее инициировал. 
Вы не можете выполнять DDL в удаленной базе по связи баз данных. Это — прямое следствие предыдущего ограничения. DDL выполняет фиксацию. Нельзя выполнить фиксацию ни с одного сайта, кроме инициирующего, а потому нельзя выполнять DDL по связи баз данных. 
Нельзя выдать SAVEPOINT по связи баз данных. Короче говоря, вы не можете выдать ни одного оператора управления транзакциями по связи баз данных. Все управление транзакциями наследуется от сеанса, который первоначаль­но открывает связи баз данных. Вы не можете осуществлять другого управ­ления транзакциями на распределенных экземплярах в транзакции. 

Недостаток управления транзакциями по связи баз данных также оправдан, по­скольку инициирующий сайт — единственный, имеющий список всех, кто вовле­чен в транзакцию. Если в нашей конфигурации из трех сайтов сайт 2 попытается зафиксировать транзакцию, у него не будет никаких сведений о том, что в ней уча­ствует сайт 3. Поэтому в Oracle только сайт 1 может выдать команду на фиксацию. В этой точке для сайта 1 допустимо делегировать ответственность за управление распределенной транзакцией другому сайту. 
Мы можем указать, какой сайт будет действительным фиксирующим сайтом, устанавливая параметр COMMIT_POINT_STRENGTH (“сила точки фиксации”) сайта. Сила точки фиксации ассоциирует относительный уровень важности с сервером в распределенной транзакции. Чем более важен сервер (больше доступных данных должно быть на нем), тем более вероятно, что именно он будет координировать распределенную транзакцию. Вам может понадобиться это в случае, когда необ­ходимо выполнить распределенную транзакцию между вашим рабочим сервером и тестовым сервером. Поскольку координатор транзакции никогда не сомневает­ся в исходе транзакции, будет лучше, если рабочий сервер станет координировать распределенную транзакцию. Вам не нужно особо беспокоиться о вашем тестовом сервере — что на нем вдруг окажутся открытые транзакции или блокированные ресурсы. Вам определенно стоит беспокоиться, если подобное случится на рабочем сервере. 
В невозможности выполнения DDL по связи баз данных вообще нет ничего плохого. Во-первых, DDL случается редко. Вы выполняете операторы DDL при ин­сталляции или обновлении. Рабочие системы не выполняют DDL (по крайней мере, не должны). Во-вторых, все-таки существует способ запустить DDL через связь баз данных — воспользоваться средством планирования заданий DBMS_JOB или, в 
Oracle 10— пакетом планировщика DBMS_SCHEDULER. Вместо того чтобы пытаться выполнить DDL по связи, вы используете связь для планирования удаленного за­дания, чтобы оно выполнилось, как только вы осуществите фиксацию. Таким об­разом, задание запустится на удаленной машине, оно не будет частью распреде­ленной транзакции и потому сможет выполнить операторы DDL. Фактически это метод, посредством которого сервер репликации Oracle (Oracle Replication Server) выполняет распределенные команды DDL, чтобы осуществить репликацию схемы.
 









jAntivirus