- •Оглавление
- •Предисловие
- •Введение
- •Часть I Обзор Глава 1 "Расслоение" системы
- •Развитие модели слоев в корпоративных программных приложениях
- •Три основных слоя
- •Где должны функционировать слои
- •Глава 2 Организация бизнес-логики
- •Выбор типового решения
- •Глава 3 Объектные модели и реляционные базы данных
- •Архитектурные решения
- •Функциональные проблемы
- •Считывание данных
- •Взаимное отображение объектов и реляционных структур
- •Отображение связей
- •Наследование
- •Реализация отображения
- •Двойное отображение
- •Использование метаданных
- •Соединение с базой данных
- •Другие проблемы
- •Дополнительные источники информации
- •Глава 4 Представление данных в Web
- •Типовые решения представлений
- •Типовые решения входных контроллеров
- •Дополнительные источники информации
- •Глава 5 Управление параллельными заданиями
- •Проблемы параллелизма
- •Контексты выполнения
- •Изолированность и устойчивость данных
- •Стратегии блокирования
- •Предотвращение возможности несогласованного чтения данных
- •Разрешение взаимоблокировок
- •Транзакции
- •Типовые решения задачи обеспечения автономного параллелизма
- •Параллельные операции и серверы приложений
- •Дополнительные источники информации
- •Глава 6 Сеансы и состояния
- •В чем преимущество отсутствия "состояния"
- •Состояние сеанса
- •Глава 7 Стратегии распределенных вычислений
- •Соблазны модели распределенных объектов
- •Интерфейсы локального и удаленного вызова
- •Когда без распределения не обойтись
- •Сужение границ распределения
- •Интерфейсы распределения
- •Глава 8 Общая картина
- •Предметная область
- •Источник данных
- •Платформы и инструменты
- •Другие модели слоев
- •Часть II Типовые решения Глава 9 Представление бизнес-логики Сценарий транзакции (Transaction Script)
- •Модель предметной области (Domain Model)
- •Модуль таблицы (Table Module)
- •Слой служб (Service Layer)
- •Глава 10 Архитектурные типовые решения источников данных Шлюз таблицы данных (Table Data Gateway)
- •Шлюз записи данных (Row Data Gateway)
- •Активная запись (Active Record)
- •Преобразователь данных (Data Mapper)
- •Глава 11 Объектно-реляционные типовые решения, предназначенные для моделирования поведения Единица работы (Unit of Work)
- •Коллекция объектов (Identity Map)
- •Загрузка по требованию (Lazy Load)
- •Глава 12 Объектно-реляционные типовые решения, предназначенные для моделирования структуры Поле идентификации (Identity Field)
- •Отображение внешних ключей (Foreign Key Mapping)
- •Отображение с помощью таблицы ассоциаций (Association Table Mapping)
- •Отображение зависимых объектов (Dependent Mapping)
- •Внедренное значение (Embedded Value)
- •Сериализованный крупный объект (Serialized lob)
- •Наследование с одной таблицей (Single Table Inheritance)
- •Наследование с таблицами для каждого класса (Class Table Inheritance)
- •Наследование с таблицами для каждого конкретного класса (Concrete Table Inheritance)
- •Преобразователи наследования (Inheritance Mappers)
- •Глава 13 Типовые решения объектно-реляционного отображения с использованием метаданных Отображение метаданных (Metadata Mapping)
- •Объект запроса (Query Object)
- •Хранилище (Repository)
- •Глава 14 Типовые решения, предназначенные для представления данных в Web Модель-представление-контроллер (Model View Controller)
- •Контроллер страниц (Page Controller)
- •Контроллер запросов (Front Controller)
- •Представление по шаблону (Template View)
- •Представление с преобразованием (Transform View)
- •Двухэтапное представление (Two Step View)
- •Контроллер приложения (Application Controller)
- •Глава 15 Типовые решения распределенной обработки данных Интерфейс удаленного доступа (Remote Facade)
- •Объект переноса данных (Data Transfer Object)
- •Глава 16 Типовые решения для обработки задач автономного параллелизма Оптимистическая автономная блокировка (Optimistic Offline Lock)
- •Пессимистическая автономная блокировка (Pessimistic Offline Lock)
- •Блокировка с низкой степенью детализации (Coarse-Grained Lock)
- •Неявная блокировка (Implicit Lock)
- •Глава 17 Типовые решения для хранения состояния сеанса Сохранение состояния сеанса на стороне клиента (Client Session State)
- •Сохранение состояния сеанса на стороне сервера (Server Session State)
- •Сохранение состояния сеанса в базе данных (Database Session State)
- •Глава 18 Базовые типовые решения Шлюз (Gateway)
- •Преобразователь (Mapper)
- •Супертип слоя (Layer Supertype)
- •Отделенный интерфейс (Separated Interface)
- •Реестр (Registry)
- •Объект-значение (Value Object)
- •Деньги (Money)
- •Частный случай (Special Case)
- •Дополнительный модуль (Plugin)
- •Фиктивная служба (Service Stub)
- •Множество записей (Record Set)
- •Список типовых решений
- •Шпаргалка
- •Как управлять сложным потоком функций приложения?
- •Как взаимодействовать с базой данных?
- •Как избежать загрузки в оперативную память всего содержимого базы данных?
- •Как сохранить структуры наследования в реляционной базе данных?
Контексты выполнения
Все операции, выполняемые системой, протекают в определенном контексте, причем зачастую более чем в одном. Общепринятой терминологии для обозначения контекстов выполнения не существует, и потому ниже введены определения, которые будут использоваться в дальнейшем.
В аспекте взаимодействия программной системы с внешним миром можно выделить два важных контекста — запрос и сеанс. Запрос (request) соответствует отдельно взятому обращению к системе со стороны внешнего субъекта-клиента. Обработка запроса является прерогативой сервера; обычно подразумевается, что клиент, инициировавший запрос, ожидает ответа на него. При использовании некоторых протоколов клиенту разрешается прерывать запрос до получения ответа, но такие ситуации встречаются сравнительно редко. Чаще клиент имеет возможность послать другой запрос, противоречащий исходному (скажем, отправить запрос с заказом, а затем отменить заказ). По мнению клиента, связь двух запросов вполне очевидна, но конкретный протокол может и не донести эту информацию до сервера.
Сеанс (session) — это долговременный процесс взаимодействия клиента и сервера. В частном случае сеанс может включать только один запрос, но более характерна ситуация, когда он охватывает серию запросов, посылаемых пользователем в логической последовательности. Обычно сеанс начинается с подключения клиента к системе и служит средой выполнения некоторого множества действий, включая отправку запросов к базе данных и осуществление одной или нескольких бизнес-транзакций (о них речь идет ниже). В завершение сеанса пользователь отключается от системы явно либо просто закрывает приложение, полагая, что система отреагирует на это надлежащим образом.
Программное обеспечение сервера корпоративных приложений может выступать в двух ипостасях — как сервер для клиента приложения и как клиент других систем. Поэтому нужно иметь в виду и возможность одновременного протекания нескольких сеансов с участием сервера (например, HTTP-сеанса с клиентом и сеанса взаимодействия с СУБД).
Рассмотрим другую пару понятий, происходящих из предметной области операционных систем, — "процесс" и "поток вычислений". Процесс (process) — это всеобъемлющий контекст выполнения, обеспечивающий высокий уровень изоляции охватываемых им данных от внешнего мира. Поток вычислений (thread) — более "легковесный" активный агент; в контексте одного процесса может функционировать целое множество потоков. Модель многопоточного программирования находит самое широкое применение, поскольку обеспечивает высокий уровень использования вычислительных ресурсов благодаря возможности формирования многочисленных запросов в русле единого процесса. Однако потоки, как правило, имеют доступ к одним и тем же массивам оперативной памяти, что приводит к естественным проблемам. Некоторые среды позволяют управлять доступом к ресурсам и создавать изолированные потоки (isolated threads), которые, в частности, способны обращаться к собственным областям памяти.
Одна из трудностей восприятия контекстов выполнения состоит в том, что они в действительности не упорядочены в такой степени, как того хотелось бы. В теории каждый сеанс должен быть связан исключительно с одним процессом на протяжении всего времени его протекания. Поскольку процессы в достаточной мере изолированы друг от друга, это могло бы снизить опасность возникновения конфликтов из-за параллелизма. На сегодня, однако, не известна ни одна серверная платформа, которая функционирует подобным образом. Ближайшая альтернатива связана с активизацией нового процесса для обработки каждого поступившего запроса; именно такая схема использовалась в ранних Web-системах, основанных на сценариях Perl. Сейчас ее стараются избегать, так как старт процесса сопряжен с расходованием избыточных ресурсов. Но обычной практикой является обработка процессом только одного запроса в каждый момент времени; это позволяет избавиться от многих проблем, обусловленных параллельным функционированием нескольких потоков.
При работе с системой баз данных следует различать еще один важный контекст выполнения — контекст транзакции (transaction). Транзакции способны соединять в себе несколько запросов, которые клиенту хотелось бы трактовать как единый запрос. Команды, составляющие транзакцию, могут быть адресованы приложением к СУБД (системные транзакции) или пользователем к приложению (бизнес-транзакции). Эти термины обсуждаются ниже.
