Введение в программирование на C# 2.0

       

Транзакция


Под транзакцией понимается неделимая с точки зрения воздействия на базу данных последовательность операторов манипулирования данными:

  • чтения,
  • удаления,
  • вставки,
  • модификации, приводящая к одному из двух возможных результатов:
  • либо последовательность выполняется, если все операторы правильные,
  • либо вся транзакция откатывается, если хотя бы один оператор не может быть успешно выполнен.

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

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

  • Atomicity – неделимость. Транзакция неделима в том смысле, что представляет собой единое целое. Все ее компоненты либо имеют место, либо нет. Не бывает частичной транзакции. Если может быть выполнена лишь часть транзакции, она отклоняется.
  • Consistency – согласованность. Транзакция является согласованной, потому что не нарушает бизнес-логику и отношения между элементами данных. Это свойство очень важно при разработке клиент-серверных систем, поскольку в хранилище данных поступает большое количество транзакций от разных систем и объектов. Если хотя бы одна из них нарушит целостность данных, то все остальные могут выдать неверные результаты.
  • Isolation – изолированность. Транзакция всегда изолированна, поскольку ее результаты самодостаточны. Они не зависят от предыдущих или последующих транзакций – это свойство называется сериализуемостью и означает, что транзакции в последовательности независимы.
  • Durability – устойчивость. Транзакция устойчива. После своего завершения она сохраняется в системе, которую ничто не может вернуть в исходное (до начала транзакции) состояние, т.е. происходит фиксация транзакции, означающая, что ее действие постоянно даже при сбое системы. При этом подразумевается некая форма хранения информации в постоянной памяти как часть транзакции.


Указанные выше правила реализуются непосредственно источником данных. На программиста возлагаются обязанности по созданию эффективных и логически верных алгоритмов обработки данных. Он решает, какие команды должны выполняться как одна транзакция, а какие могут быть разбиты на несколько последовательно выполняемых транзакций.

Работа с транзакцией предполагает следующую последовательность действий:

  • Инициализация транзакции.


Обеспечивается вызовом метода BeginTransaction() от имени объекта Connection, представляющего открытое соединение. В результате выполнения этого метода возвращается ссылка на объект – представитель класса Transaction, который должен быть записан в свойство Transaction всех объектов-команд, которые должны быть задействованы в данной транзакции.
  • Выполнение команд – участников транзакции с анализом их возвращаемых значений (обычно этот анализ сводится к тривиальному размещению всех операторов, связанных с выполнением транзакции в один try-блок).
  • Если все команды выполняются удовлетворительно, от имени объекта – представителя класса Transaction вызывается метод Commit(), который подтверждает изменение состояния источника данных. В противном случае (блок catch), от имени объекта – представителя класса Transaction вызывается метод Rollback(), который отменяет ранее произведенные изменения состояния Базы данных.


  • Ниже приводится пример исполнения транзакции с помощью объекта соединения класса OleDbConnection с именем xConnection и пары объектов OleDbCommand с именами xCommand1 и xCommand2:

    System.Data.OleDb.OleDbTransaction xTransaction = null; try { xConnection.Open(); // Создается объект транзакции. xTransaction = xConnection.BeginTransaction(); // Транзакция фиксируется в командах. xCommand1.Transaction = xTransaction; xCommand2.Transaction = xTransaction; // Выполнение команд. xCommand1.ExecuteNonQuery(); xCommand2.ExecuteNonQuery(); // Если ВСЕ ХОРОШО и мы все еще здесь – ПРИНЯТЬ ТРАНЗАКЦИЮ! xTransaction.Commit(); } catch { // Если возникли осложнения – отменяем транзакцию. xTransaction. Rollback(); } finally { // В любом случае соединение закрывается. xConnection.Close(); }


    Содержание раздела