Oracle для профессионалов



              

Избегайте длительных транзакций в среде MTS - часть 2


Простое решение "в лоб" состоит в запуске большего количества разделяемых серверов, но в конечном итоге придется запускать разделяемый сервер для каждого пользователя, а это неприемлемо для системы с тысячами пользователей (как та, что создавалась в рассматриваемом проекте). Это не только создает узкие места в самой системе (чем большим количеством процессов приходится управлять, тем больше процессорного времени на это уходит), но и просто не соответствует целям создания режима MTS.

Реальное решение этой проблемы оказалось простым: не выполнять продолжительные транзакции на сервере, работающем в режиме MTS. А вот реализация этого решения оказалась сложнее. Это можно было сделать несколькими способами, но все они требовали существенных изменений архитектуры. Самым подходящим способом, требующим минимальных изменений, оказалось использование средств расширенной поддержки очередей (Advanced Queues — AQ).

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

Итак, вместо выполнения 45-секундного процесса, компонент должен помещать запрос со всеми необходимыми входными данными в очередь и выполнять его асинхронно, а не синхронно. В этом случае пользователю не придется ждать ответа 45 секунд, то есть система становится более динамичной.

Хотя, судя по описанию, этот подход прост (подключение механизма AQ полностью решает проблему), потребовалось сделать намного больше. Этот 45-секундный процесс генерировал идентификатор транзакции, необходимый на следующем шаге в интерфейсе для соединения таблиц — по проекту интерфейс без этого не работал. Используя механизм AQ, мы не ждем генерации идентификатора транзакции, — мы обращаемся к системе с просьбой сделать это когда-нибудь. Поэтому приложение опять оказалось в тупике. С одной стороны, мы не можем ждать завершения процесса 45 секунд, но, с другой стороны, для перехода к следующему экрану необходим сгенерированный идентификатор, а получить его можно только спустя 45 секунд. Для того чтобы решить эту проблему, пришлось синтезировать собственный поддельный идентификатор транзакции, изменить продолжительный процесс так, чтобы он принимал этот сгенерированный поддельный идентификатор и обновлял таблицу, записывая его по завершении работы, благодаря чему реальный идентификатор транзакции связывался с поддельным. То есть, вместо получения реального идентификатора в результате длительного процесса, этот идентификатор становится для процесса входными данными. Во всех "подчиненных" таблицах использовался этот поддельный идентификатор транзакции, а не реальный (поскольку генерации реального надо ждать определенное время). Нам также пришлось пересмотреть использование этого идентификатора транзакции, чтобы понять, как это изменение повлияет на другие модули, и так далее.




Содержание  Назад  Вперед