Материал: OOP_LW_1_Umnye_ukazateli_Tranzaktsii

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

функции (начать, закрепить, отменить действие). Если требуется закрепить или отменить выполненные изменения, то необходимо хранить состояние объекта на заданный момент – начало транзакции, и в момент принятия решения фиксации транзакции или уничтожать предыдущее состояние (закрепление транзакции), или возвращаться к предыдущему состоянию (отмена транзакции). Механизм транзакций можно рассмотреть на примере следующей программы.

//Пример №2. Использование механизма транзакции #include <locale.h>

#include <iostream> using namespace std;

//класс, над объектами которого выполняются транзакции template <class T1>

class Account { T1 number;

public:

Account() : number(0) {}

void set(int number) { this->number = number; } // инициализация объекта

T1 get() { return number; } // возвращается значение объекта

};

//класс поддержки транзакций

template <class T2> class Transaction {

T2* currentState; // текущее значение объекта класса

T2* prevState; // предыдущее значение объекта класса public:

Transaction() :prevState(NULL), currentState(new T2) {} // конструктор

Transaction(const Transaction & obj) : currentState(new T2(*(obj.currentState))), prevState(NULL) {}

~Transaction() { delete currentState; delete prevState; } // деструктор

Transaction& operator=(const Transaction & obj); // перегрузка операции присваивания

void show(int);//отображение состояний (предыдущего и текущего) объекта

int BeginTransactions(int); // метод начала транзакции void commit(); // метод подтветждения (коммита) транзакции void DeleteTransactions(); //метод отката транзакции

T2* operator->(); // перегрузка операции ->

};

//перегрузка оператора = template <class T2>

Transaction<T2>& Transaction<T2>::operator=(const Transaction<T2> & obj)

{

if (this != &obj) // проверка на случай obj=obj

{

delete currentState; // удаление текущего значения объекта currentState = new T2(*(obj.currentState)); // создание и

копирование

}

return *this;

}

//перегрузка оператора ->

template <class T2>

T2* Transaction<T2>::operator->()

{

return currentState;

}

//метод отображения состояния объекта template <class T2>

void Transaction<T2>::show(int account) { cout << "состояния объекта ";

if (!account) cout << "до начала транзакции " << endl; else cout << "после выполнения транзакции " << endl;

if (prevState) cout << "prevState = " << prevState->get() << endl;

//предыдущее состояние

else cout << "prevState = NULL" << endl;

cout << "currentState = " << currentState->get() << endl; // текущее состояние

}

template <class T2>

int Transaction<T2>::BeginTransactions(int number) {// метод начала транзакции

delete prevState; // удаление предыдущего значения prevState = currentState; // текущее становится предыдущим

currentState = new T2(*prevState); // создание нового значения текущего состояния

if (!currentState) return 0; // ошибка (необходимо отменить действие)

currentState->set(number); // изменение состояния объекта return 1; // успешное окончание транзакции

}

template <class T2>

void Transaction<T2>::commit() {// метод подтветждения (коммита)

транзакции

delete prevState; // удаление предыдущего значения prevState = NULL; // предыдущего состояния нет

}

template <class T2>

void Transaction<T2>::DeleteTransactions() {//метод отката транзакции if (prevState != NULL) {

delete currentState; // удаление текущего значения currentState = prevState; // предыдущее становится текущим prevState = NULL; // предыдущего состояния нет

}

}

int main() {

Transaction<Account<int>> firstTransaction; setlocale(LC_ALL, "Russian");

firstTransaction->set(5); // начальная инициализация объекта firstTransaction.show(0);

cout << "НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ ПРОШЛА УСПЕШНО" << endl; cout << endl;

cout << "ПЕРВАЯ ТРАНЗАКЦИЯ НАЧАТА СО ЗНАЧЕНИЕМ 10" << endl;

if (firstTransaction.BeginTransactions(10)) // начало транзакции

(изменение объекта)

{

firstTransaction.show(1);

firstTransaction.commit(); // закрепление транзакции

}

cout << "ПЕРВАЯ ТРАНЗАКЦИЯ ПРОШЛА УСПЕШНО" << endl; cout << endl;

firstTransaction.DeleteTransactions(); // отмена транзакции при ошибке

cout << "ПЕРВАЯ ТРАНЗАКЦИЯ БЫЛА ОТМЕНЕНА" << endl; firstTransaction.show(0);

cout << endl;

cout << "ВТОРАЯ ТРАНЗАКЦИЯ НАЧАТА CO ЗНАЧЕНИЕМ 2" << endl;

if (firstTransaction.BeginTransactions(2)) { // начало транзакции

(изменение объекта) firstTransaction.show(1);

firstTransaction.commit(); // закрепление транзакции

}

cout << "ВТОРАЯ ТРАНЗАКЦИЯ ПРОШЛА УСПЕШНО" << endl; firstTransaction.show(0);

return 0;

}

Результаты работы программы:

ВОПРОСЫ И УПРАЖНЕНИЯ ДЛЯ ЗАКРЕПЛЕНИЯ МАТЕРИАЛА:

1.Каковы особенности и использования динамической памяти в С++?

2.С какой целью используются smart-указатели? Каковы особенности их использования? Что представляет собой smart-указатель?

3.Что такое утечка памяти в программировании?

4.Что такое висячая ссылка (висячий указатель)?

5.Какие виды интеллектуальных указателей предоставляет библиотека С++?

6.Что собой представляет идиома программирования RAII?

7.Что такое транзакция в программировании? В чем состоит механизм транзакций?

8.Какие основные операции используются при реализации механизма транзакций?

ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ:

1.Изучить краткие теоретические сведения.

2.Ознакомиться с материалами литературных источников и материалами лекций.

3.Ответить на контрольные вопросы.

4.Разработать алгоритм программы.

5.Написать, отладить и выполнить программу.

6.Написать электронный отчет по выполненной лабораторной работе.

ВАРИАНТЫ ИНДИВИДУАЛЬНЫХ ЗАДАНИЙ:

1.Разработать набор классов (минимум 5 классов) по теме издательство

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

2.Разработать набор классов (минимум 5 классов) по теме делопроизводство. Использовать smart-указатели для создания программы учета делопроизводства в учреждении образования. Имеется несколько объектов документации и некоторое количество сотрудников учреждения образования, которые работают с документацией. Документ считается сформированным, когда с ним не работает ни один сотрудник. Разработанный набор классов должен иметь параметры типа. Все классы должны иметь методы получения и изменения своих полей. Реализовать механизм транзакций, который позволит сотрудникам откатывать изменения, внесенные в документы.

3.Разработать набор классов (минимум 5 классов) по теме сотрудники ИТ-

организации. Использовать smart-указатели для создания программы учета сведений о сотрудниках и расчета для них заработной платы. Разработанный набор классов должен иметь параметры типа. Все классы должны иметь методы получения и изменения своих полей. Реализовать механизм транзакций, который позволит откатывать изменения, внесенные в сведения о сотрудниках ИТ-организации. Предусмотреть возможность автоматического «отката» к предыдущему состоянию данных о сотруднике, если текущее состояние является неудовлетворительным. Смоделировать данную ситуацию.

4.Разработать набор классов (минимум 5 классов) по теме использование текстового редактора пользователями с автоматическим сохранением данных в файл. Редактор должен поддерживать возможность отмены внесенных изменений (отменить ввод, Undo, Ctrl+Z) и восстановления отмененной информации (вернуть ввод, Ctrl+Y, Redo). Для хранения историй модификации файла использовать список (его рациональную организацию определить самостоятельно). Разработанный набор классов должен иметь параметры типа. Все классы должны иметь методы получения и изменения своих полей. Использовать smart-указатели для создания программы, которая определяет возможность самостоятельного закрытия файла (т.е. данные файла сохранены и с ним никто сейчас не работает).

5.Разработать набор классов (минимум 5 классов) по теме банковские операции. Использовать smart-указатели для создания программы учета проводимых банковский операций и подсчета количества различных видов (переводы денежных

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

6.Разработать набор классов (минимум 5 классов) по теме «Розничная продажа товаров и услуг». Использовать smart-указатели для создания программы учета продаваемых и закупаемых товаров. Реализовать механизм транзакций, который позволит откатывать изменения, если данные о товаре введены неверно (например, покупатель отказался оплачивать товар). Разработанный набор классов должен иметь параметры типа. Все классы должны иметь методы получения и изменения своих полей. Программа должна обеспечивать вывод информации об осуществленных покупках и итоговой сумме только по запросу клиента.

7.Разработать набор классов (минимум 5 классов) по теме «Тестирование знаний студентов», включающий обязательно следующие классы: «Тест» (название теста, тема теста, перечень вопросов, перечень полученных ответов), «Пользователь» (ФИО, факультет, номер группы), «Ответ» (дата выполнения теста, ФИО выполнившего тест). Использовать smart-указатели для создания программы учета полученных ответов на тесты. Реализовать механизм транзакций, который позволит откатывать изменения, внесенные в ответ. Все классы должны быть параметризированными и содержать функции получения и изменения всех полей. Программа должна обеспечивать вывод итоговой информации о выполнении тестов.