|
Транзакции и отмена Решение проблемы транзакций в значительной степени связано с проблемами отмены и многопоточных итераторов, поэтому сначала мы поговорим о транзакциях. Итак, мы хотим предотвратить обновление некоторого объекта более чем одной транзакцией. Похоже, в решении этой задачи нам помогут указатели образов. Давайте посмотрим свежим взглядом на обобщенный указатель образов, приведенный в начале главы: template <class Type> class ImagePtr { private: Type* current; // Текущий образ, предоставляемый компоненту Type* undo; // Предыдущий образ public: ImagePtr(); ImagePtr(const ImagesPtr<Type>& ip); ~ImagePtr(); ImagePtr<Type>& operator=(const ImagePtr<Type>& ip); void Snapshot(); void Commit(); void Rollback(); Type* operator->() const; }; Для мира транзакций придется внести ряд изменений:
2. Объект не может быть изменен при снятой блокировке. 3. Заблокированный объект может быть измене лишь объектом, который принадлежит транзакции, установившей блокировку. Следовательно, нам придется создать некоторое представление для транзакции, а заодно - поразмять мышцы С++ и построить соответствующую семантику. Транзакции будут представлены классом Transaction. Для блокировок мы воспользуемся специальным обновляющим указателем. Иначе говоря, обычные клиенты работают с умным указателем, не допускающим обновления, а клиенты транзакции-владельца получают доступ к другому указателю с возможностью обновления. Ниже приведена прямолинейная (хотя необязательно самая эффективная) реализация этой архитектуры. Позднее мы снимем эти упрощающие ограничения и расширим архитектуру: 1. Нас интересует только отмена изменений в существующих объектах, а не отмена создания и уничтожения объектов в процессе транзакции. 2. Вопрос о том, когда именно должна устанавливаться блокировка объекта выходит за рамки описанной упрощенной архитектуры. |
Copyright 2005. Климов Александр. All Right Reserved.