|
Транзакции и блокировки В действительности транзакция представляет собой нечто иное, чем коллекцию указателей образов, в которой имеется несколько функций для перебора. Одна из трудностей состоит в том, что одна транзакция может обновлять любое число объектов, относящихся к различным типам. Следовательно, класс транзакции должен быть расписан так, чтобы он мог работать с любыми типами - похоже, речь идет об абстрактном базовом классе. // В файле Transaction.h class Lock { friend class Transaction; protected: Transaction* transaction; // Транзакция, которой принадлежит this Lock() : transaction(NULL) {} void RegisterLock(Transaction* t) { if (transaction != NULL) { // Конфликт - уже имеется другой владелец cerr << "Lock::RegisterLock - already locked" << endl; } else { t->AddLock(this); transaction = t; } } virtual ~Lock() {} virtual void Rollback() = 0; virtual void Commit() = 0; }; class Transaction { friend class Lock; // Чтобы предоставить доступ к AddLock() private: SafeSet<Lock>* locks; void AddLock(Lock*); // Включить блокировку в транзакцию public: ~Transaction(); void Commit(); // Закрепить все образы void Rollback(); // Отменить все образы bool OwnsLock(Lock*); // Истина, если блокировка // принадлежит транзакции }; Класс Transaction поддерживает коллекцию блокировок с помощью гипотетического шаблона Collection. Функция RegisterLock() включена в базовый класс Lock и потому может обратиться к закрытой функции AddLock() класса Transaction. Дружба не наследуется, поэтому объявление другом класса Lock не делает друзьями его производные классы. Реализации выглядят довольно просто. void Transaction::AddLock(Lock* lock) { *locks += lock; // Использует перегрузку += для коллекции } void Transaction::Commit() { SafeSetIterator<Lock>* iter = locks->Iterator(); while (iter->More()) iter->Next()->Commit(); delete iter; } void Transaction::Rollback() { SafeSetIterator<Lock>* iter = locks->Iterator(); while (iter->More()) iter->Next()->Rollback(); delete iter; } bool Transaction::OwnsLock(Lock* lock) { return *locks >= lock; } Предполагается, что шаблон Collection содержит функцию DeleteAll() для удаления всех объектов; что перегруженный оператор += (операторная функция operator+=(Type*)) включает элемент в коллекцию; что перегруженный оператор >= определяет принадлежность к коллекции, а функция Iterator() возвращает вложенный итератор. Это обобщенные условия; используйте те, которые действуют в вашем случае. |
Copyright 2005. Климов Александр. All Right Reserved.