Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:
Говоря про активацию по необходимости, следует упомянуть про пул объектов. Это еще один сервис, предоставляемый СОМ+ как средство решения проблемы масштабируемости приложения. При активации объект может либо формироваться заново, либо извлекаться из пула ранее построенных объектов данного типа. При деактивизации вместо уничтожения некоторого объекта его можно вернуть в пул для последующего использования. Выбор за разработчиком.
Помещение объекта в пул и извлечение его из пула выполняется автоматически при условии, что соответствующий класс удовлетворяет ряду требований.
Прежде всего, при конфигурировании класса на вкладке Activation
Далее приведены требования к классу, экземпляры которого можно помещать в пул:
• Класс должен реализовать стандартный интерфейс IObjectControl
Данный интерфейс имеет три метода, которые автоматически вызываются СОМ+.
? Activate
Этот метод вызывается автоматически при активации объекта. Здесь следует выполнить инициализацию данных объекта, получить указатель на объект контекста,
? Deactivate
Этот метод вызывается автоматически при деактивизации объекта. Здесь следует освободить все ресурсы, захваченные объектом,
? CanBePooled
Этот метод вызывается автоматически на последнем этапе деактивации. Тут объект может отказаться по каким-либо причинам от помещения в пул. В этом случае он просто будет уничтожен.
• Допустимые потоковые модели: Free, Both, Neutral
Иными словами, объект, допускающий помещение в пул, должен жить в МТА или NA апартаменте. Это связано с тем, что один поток сформирует данный объект и поместит его в пул, и совсем другому потоку понадобится извлечь его из пула и вызвать какой-либо из его методов.
• Класс должен допускать агрегацию, но сам не должен агрегировать другие помещаемые в пул объекты.
• Класс не должен использовать FTM для оптимизации маршализации указателя на интерфейс.
Распространение транзакции
Менеджер транзакций в СОМ+ имеет имя координатор распределенных транзакций — DTC (Distributed Transaction Coordinator). При активации объекта, который должен быть корнем некоторой новой транзакции, DTC порождает новую транзакцию, которая получает уникальный идентификатор (GUID). Этот идентификатор хранится к объекте контекста данного объекта. Кроме того, объект контекста хранит два бита, модифицируя которые объект информирует DTC о своем отношении к текущей транзакции. Эти биты иногда называют бит голосования и бит деактивации по возврату.
• Бит голосования
Принимает значение 1, если объект в данный момент удовлетворен ходом дел и собирается голосовать за успешное завершение транзакции если ничего не изменится.
По умолчанию именно это значение выбирается при активации объекта.
Принимает значение 0, если объект в данный момент не удовлетворен результатами и собирается голосовать за откат назад.
• Бит деактивации по возврату
Если данный бит установлен в 1, то сразу же после возврата из выполняемого метода данный объект будет деактивирован, а значение его бита голосования будет учтено DTC при принятии решения об успешном завершении транзакции или об откате назад.
Если данный бит установлен в 0, объект еще не готов к деактивации и по возврату из текущего метода будет ожидать новых вызовов. Именно это значение устанавливается по умолчанию при активации объекта.
Для модификации указанных битов имеется несколько возможностей. Рассмотрим одну из них. Интерфейс IObjectContext объекта контекста имеет четыре метода, которые можно использовать для задания значений этих битов (см. таблицу 3.2)
Заметим, что интерфейс IContextState объекта контекста имеет методы, позволяющие узнать текущее значение указанных битов и задать их новые значения не парами, а по одному.
Наконец, используя Components Services, можно пометить некоторый метод как Auto-Done. В этом случае при возврате из этого метода произойдет деактивация объекта и он будет голосовать за успешное завершение текущей транзакции или за откат в зависимости от того, завершился ли вызов данного метода нормально или с ошибкой. При использовании указанных выше интерфейсов этот режим перекрывается явным заданием битов голосования и деактивизации.
Распространение транзакции происходит как обычно путем активации новых объектов и путем обращения к системам хранения данных. В последнем случае соответствующий менеджер ресурса регистрируется у DTC для участия в текущей транзакции.
Завершение транзакции
Завершается транзакция в следующих случаях
• Корневой объект транзакции деактивирован после возврата из метода, где был установлен бит деактивации
В этом случае DTC анализирует биты голосования всех ранее вовлеченных в транзакцию (в том числе и деактивированных) объектов. Если все голосуют за успешное завершение транзакции, то начинается выполнения двух-фазного протокола. Заметим, что прикладные компоненты, вовлеченные в транзакцию, деактивируются до окончательного завершения транзакции. Корневой объект может информировать клиента об успехе или неудаче выполненных им действий, но если произойдет сбой на уровне отдельного менеджера ресурсов и во время двух-фазного протокола произойдет откат, информировать клиента об этом будет некому.
Если хотя бы для одного объекта бит голосования равен 0, выполняется откат назад без выполнения двух-фазного протокола.
• Корневой объект был уничтожен в связи с тем, что клиент освободил все указывающие на объект ссылки
В этом случае DTC завершает транзакцию и выполняется откат назад без выполнения двух-фазного протокола.
• Закончился временной интервал, выделенный на текущую транзакцию
По умолчанию длительность транзакции не превышает 60 секунд. По их истечении DTC завершает транзакцию и выполняется откат назад без выполнения двух-фазного протокола.