Тарифы Услуги Сим-карты

Руководство по Spring. Управление транзакциями

Концепция транзакций - неотъемлемая часть любой клиент-серверной базы данных.

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

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

уменьшение баланса исходящего счета;

увеличение баланса принимающего счета.

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

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

BEGIN TRAN - объявление начала транзакции (в журнале транзакций фиксируются первоначальные значения изменяемых данных и момент начала транзакции).

COMMIT TRAN - фиксация транзакции (если в теле транзакции не было ошибок, то эта команда предписывает серверу зафиксировать все изменения, сделанные в транзакции, после чего в журнале транзакций помечается, что изменения зафиксированы и транзакция завершена).

ROLLBACK TRAN - откат транзакции (когда сервер встречает эту команду, происходит откат транзакции (отмена всех изменений), восстанавливается первоначальное состояние системы и в журнале транзакций отмечается, что транзакция была отменена).

Рассмотрим следующий пример.

Откройте новое окно запроса и выберите Sales в качестве активной базы данных

BEGIN TRANSACTION

Будет запущена транзакция. Все модификации данных в этом соединении не будут видны для других соединений.

Введите и выполните следующий запрос

VALUES ("Новый город")

Чтобы проверить, что модификация прошла успешно, введите и выполните следующий запрос

В таблице появилась новая запись, но эти изменения видны только в данном соединении

Откройте новое окно запроса, введите и выполните в нем предыдущий запрос. Запрос не вернет результатов, поскольку он ждет завершения транзакции, запущенной в другом окне.

Вернитесь в первое окно, введите и выполните следующий запрос

ROLLBACK TRANSACTION

Модификация данных отменена. Вернитесь во второе окно. Обратите внимание, что запрос выполнился и вернул данные. Добавленная строка отсутствует.

Операция оформления нового заказа предполагает добавление новых записей сразу в две таблицы: Order и OrdItem. Реализуем данную двойную операцию в виде единой транзакции:

INSERT (IdCust)

INSERT OrdItem(IdOrd,IdProd,Qty,Price)

VALUES (SCOPE_IDENTITY(),1,1,5)

Транзакция Transaction включает одно или несколько изменений в базе данных, которые после выполнения либо все фиксируются (commit ), либо все откатываются назад (rollback ). При вызове метода commit или rollback текущая транзакция заканчивается и начинается другая.

По умолчанию каждое новое соединение находится в режиме автофиксации (autocommit = true ). Это означает автоматическую фиксацию (commit) транзакции после выполнения каждого запроса. В этом случае транзакция включает только одно изменение (один запрос).

Если autocommit запрещен, т.е. равен false, то транзакция не заканчивается до явного вызова commit или rollback, включая, таким образом, все выражения, выполненные с момента последнего вызова commit или rollback. В этом случае все SQL-запросы в транзакции фиксируются или откатываются группой.

Метод фиксации commit завершает все изменения в БД, проделанные SQL-выражением, и снимает также все блокировки, установленные транзакцией. Метод rollback наоборот - не сохранит изменения и восстановит исходное состояние на момент начала транзакции.

Иногда пользователю нужно, чтобы какое-либо изменение не вступило в силу до тех пор, пока не вступит в силу предыдущее изменение. Этого можно достичь запрещением autocommit и группировкой обоих запросов в одну транзакцию. Если оба изменения произошли успешно, то вызывается метод commit , который переносит эффект от этих изменений в БД; если одно или оба запроса не прошли, то вызывается метод rollback , который возвращает прежнее состояние БД.

Большинство JDBC-драйверов поддерживают транзакции. В действительности драйвер, соответствующий спецификации JDBC, обязан поддерживать их. Интерфейс DatabaseMetaData позволяет получить информацию об уровнях изолированности транзакций, которые поддерживаются данной СУБД.

Пример использования транзакции - commit, autocommit

Connection connection = ...; // Сброс автофиксации connection.setAutoCommit(false); // Первая транзакция PreparedStatement updateSales = connection.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?"); updateSales.setInt(1, 50); updateSales.setString(2, "Colombian"); updateSales.executeUpdate(); // Вторая транзакция PreparedStatement updateTotal = connection.prepareStatement("UPDATE COFFEES SET TOTAL = TOTAL + ? WHERE COF_NAME LIKE ?"); updateTotal.setInt(1, 50); updateTotal.setString(2, "Colombian"); updateTotal.executeUpdate(); // Завершение транзакции connection.commit(); // Восстановление по умолчанию connection.setAutoCommit(true);

В примере для соединения Connection режим автофиксации отключен и два оператора updateSales и updateTotal будут зафиксированы вместе при вызове метода commit .

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

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

Уровни изолированности транзакций, dirty read

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

Допустим, что один из пользователей обновляет параметры заказчика (адрес, телефон, email) и программа требует подтверждения выполнения транзакции. В это же время другой пользователь читает информацию из базы данных о данном заказчике. Прочитает ли второй пользователь новые и не подтвержденные данные, или будет читать старые? Ответ зависит от уровня изоляции транзакции. Если транзакция разрешает другим программам читать не подтвержденные данные, то другая программа не будет ожидать окончания транзакции. Но здесь возникает компромисс - если транзакция будет отменена, то вторая другая программа может прочитать ошибочные данные.

Есть несколько способов разрешения конфликтов между одновременно выполняющимися транзакциями. Разработчик может определить уровень изолированности так, что пока одна транзакция изменяет какое-либо значение, вторая транзакция могла бы прочитать обновленное значение до того, пока первая не выполнит commit или rollback. Для этого следует установить уровень изолированности TRANSACTION_READ_UNCOMMITTED :

Connection connection; ... connection.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);

В данном коде серверу указано на возможность чтения измененных значений до того, как выполнится commit , т.е. определена возможность "грязного чтения" ("dirty read ").

По умолчанию уровень изоляции транзакций обычно установлен в READ_COMMITED .

Изменение уровня изолированности во время транзакции нежелательно, так как произойдет автоматический вызов commit, что повлечет за собой фиксацию изменений.

В связи с тем, что уровни изоляции, предлагаемые различными поставщиками СУБД, могут меняться, Вам следует обратиться к документации за дополнительной информацией. Уровни изоляции не стандартизованы для платформы J2EE.

Чем выше уровень изолированности транзакций , тем больше внимания СУБД уделяет устранению конфликтов. Интерфейс Connection определяет пять таких уровней. Минимальный из них соответствует случаю, когда транзакции не поддерживаются вовсе, а максимальный - невозможности существования более одной транзакции в любой момент времени.

Обычно, чем выше уровень изолированности, тем медленнее выполняется приложение (из-за избыточной блокировки). При выборе конкретного уровня изолированности разработчик должен найти золотую середину между потребностями в производительности и требованиями к целостности данных. Очевидно, что реально поддерживаемые уровни зависят от возможностей используемой СУБД.

При создании объекта Connection уровень его изолированности зависит от драйвера или БД. Можно вызвать метод setIsolationLevel , чтобы изменить уровень изолированности транзакций, и новое значение уровня будет установлено до конца сессии. Чтобы установить уровень изолированности только для одной транзакции, надо установить его перед выполнением транзакции и восстановить прежнее значение после ее завершения.

Типы уровней изолированности

  • TRANSACTION_NONE
    Транзакции не поддерживаются.
  • TRANSACTION_READ_COMMITTED
    Запрет на «грязное чтение» (dirty read). Данный уровень блокирует транзакциям чтение строк с неподтвержденными изменениями в них.
  • TRANSACTION_READ_UNCOMMITTED
    Разрешение на «dirty read». Данный уровень позволяет изменять строку с помощью одной транзакции и прочесть ее другой прежде, чем изменения в этой строке будут подтверждены (dirty read). Если изменения будут отменены с помощью rollback(), вторая транзакция вернет неправильную строку.
  • TRANSACTION_REPEATABLE_READ
    Запрет на «dirty read». Данный уровень препятствует транзакции от чтения строки с неподтвержденным изменением в ней, он также предотвращает ситуацию, когда одна транзакция читает строку, а вторая транзакция изменяет ее, при этом первая транзакция перечитывая строку, получает разные значения каждый раз (разовое чтение).
  • TRANSACTION_SERIALIZABLE
    Запрет на «dirty read». Данный уровень включает предотвращения из TRANSACTION_REPEATABLE_READ, более того предотвращает ситуацию, когда одна транзакция читает все строки, которые удовлетворяют условию WHERE, а вторая транзакция вставляет строку, которая удовлетворяет тому же условию WHERE, и первая транзакция, перечитывая с тем же условием, получает дополнительную «фантомную» строку при втором чтении.

Управление буферами оперативной памяти

Непосредственное управление данными во внешней памяти

Основные функции СУБД

К основным функциям, выполняемым системами управления базами данных, обычно относят следующие:

· непосредственное управление данными во внешней памяти;

· управление буферами оперативной памяти;

· управление транзакциями;

· протоколирование;

· поддержка языков баз данных.

Рассмотрим каждую из указанных функций более подробно.

Функция непосредственного управления данными во внешней памяти включает обеспечение необходимых структур внешней памяти (постоянных запоминающих устройств - как правило, магнитных дисков) как для хранения данных, непосредственно входящих в базу данных, так и для служебных целœей, к примеру для ускорения доступа к данным в некоторых случаях (обычно для этого используются индексы). Причем пользователям базы данных в общем случае не нужно знать, использует ли СУБД файловую систему и если использует, то как организованы файлы. Обычно СУБД поддерживает собственную систему именования объектов БД. Учитывая зависимость отспособа реализации СУБД может либо использовать возможности существующих файловых систем, либо работать с устройствами внешней памяти на низком уровне.

Объём информации, хранящейся в базе данных, с которой работает СУБД, обычно достаточно велик и практически всœегда превышает доступный объём оперативной памяти. При этом время доступа к данным, хранящимся в оперативной памяти, существенно меньше, чем к данным, хранящимся на устройствах внешней памяти. Очевидно, что если при обращении к любому элементу данных будет производится обмен с внешней памятью, то вся система будет работать со скоростью устройства внешней памяти.

Увеличения скорости обмена данными Можно достичь, используя буферизацию данных в оперативной памяти. При этом, даже если операционная система производит общесистемную буферизацию (как в случае ОС UNIX), этого недостаточно для целœей СУБД, которая располагает гораздо большей информацией о полезности буферизации какой-либо части базы данных. По этой причине в СУБД обычно поддерживается собственный набор буферов оперативной памяти с собственным механизмом замены буферов.

Транзакцией принято называть последовательность операций над базой данных, рассматриваемых СУБД как единое целое. В случае если всœе операции успешно выполнены, то транзакция также считается успешно выполненной и СУБД фиксирует (COMMIT) всœе изменения данных, произведенные этой транзакцией (то есть заносит изменения во внешнюю память). В случае если же хотя бы одна операция транзакции заканчивается неудачей, то транзакция считается невыполненной и производится откат (ROLLBACK) - отмена всœех изменений данных, произведенных в ходе выполнения транзакции, и возврат базы данных к состоянию до начала выполнения транзакции. Управление транзакциями крайне важно для поддержания логической целостности базы данных. Поддержка механизма транзакций является обязательным условием даже однопользовательских, а тем более для многопользовательских СУБД. То свойство, что каждая транзакция начинается при целостном состоянии базы данных и оставляет это состояние целостным после своего завершения, делает очень удобным использование понятия транзакции как единицы активности пользователя по отношению к базе данных. При соответствующем управлении параллельно выполняющимися транзакциями со стороны СУБД каждый из пользователœей может, в принципе, ощущать себя единственным пользователœем СУБД.

С управлением транзакциями в многопользовательской СУБД связаны важные понятия сериализации транзакций и сериального плана выполнения смеси транзакций. Под сериализациями параллельно выполняющихся транзакций принято понимать такое планирование их работы, при котором суммарный результат смеси транзакций эквивалентен результату их некоторого последовательного выполнения. Сериальный план выполнения смеси транзакций - это такой план, который приводит к сериализации транзакций. Попятно, что если удается добиться действительно сериального выполнения смеси транзакций, то для каждого пользователя, по инициативе которого образована транзакция, присутствие других транзакций будет незаметно (если не считать некоторого замедления работы по сравнению с однопользовательским режимом).

Существует несколько базовых алгоритмов сериализации транзакций. В централизованных СУБД наиболее распространены алгоритмы, основанные на синхронизационных захватах объектов базы данных. При использовании любого алгоритма сериализации возможны конфликты между несколькими транзакциями по доступу к объектам базы данных, В этом случае для поддержания сериализации крайне важно выполнить откат одной или нескольких транзакций. Это один из случаев, когда пользователь многопользовательской СУБД может реально (и достаточно неприятно) ощутить присутствие в системе транзакций других пользователœей.

Управление транзакциями - понятие и виды. Классификация и особенности категории "Управление транзакциями" 2017, 2018.

  • - Управление транзакциями

    Под управлением транзакциями понимается способность управлять различными операциями над данными, которые выполняются внутри реляционной СУБД. Прежде всего, имеется в виду выполнение операторов INSERT, UPDATE и DELETE. Например, после создания таблицы (выполнения оператора CREATE... .


  • - Управление транзакциями

    Транзакция - это последовательность операций над БД, рассматриваемых СУБД как единое целое. Либо транзакция успешно выполняется и СУБД фиксирует (COMMIT) изменения БД, произведенные ею, во внешней памяти, либо ни одно из этих изменений никак не отражается в состоянии БД.... .


  • - Управление транзакциями

    Транзакция - это последовательность операций над БД, рассматриваемых СУБД как единое целое. Либо транзакция успешно выполняется, и СУБД фиксирует (COMMIT) изменения БД, произведенные этой транзакцией, во внешней памяти, либо ни одно из этих изменений никак не отражается на... .


  • - Управление транзакциями, сериализация транзакций

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

  • Транзакция - это неделимая, с точки зрения воздействия на СУБД, последовательность операций манипулирования данными. Для пользователя транзакция выполняется по принципу «все или ничего », т.е. либо транзакция выполняется целиком и переводит базу данных из одного целостного состояния в другое целостное состояние , либо, если по каким-либо причинам, одно из действий транзакции невыполнимо, или произошло какое-либо нарушение работы системы, БД возвращается в исходное состояние, которое было до начала транзакции (происходит откат транзакции). С этой точки зрения, транзакции важны как в многопользовательских, так и в однопользовательских системах. В однопользовательских системах транзакции - это логические единицы работы, после выполнения которых БД остается в целостном состоянии . Транзакции также являются единицами восстановления данных после сбоев - восстанавливаясь, система ликвидирует следы транзакций, не успевших успешно завершиться в результате программного или аппаратного сбоя. Эти два свойства транзакций определяют атомарность (неделимость) транзакции. В многопользовательских системах, кроме того, транзакции служат для обеспечения изолированной работы отдельных пользователей - пользователям, одновременно работающим с одной базой данных, кажется, что они работают как бы в однопользовательской системе и не мешают друг другу.

    Транзакция или логическая единица работы БД, - это в общем случае последовательность ряда таких операций, которые преобразуют некоторое непротиворечивое состояние базы данных в другое непротиворечивое состояние, но не гарантируют сохранения непротиворечивости во все промежуточные моменты времени.

    Транзакция обладает четырьмя важными свойствами, известными как свойства АСИД :

    • (А ) Атомарность . Транзакция выполняется как атомарная операция - либо выполняется вся транзакция целиком, либо она целиком не выполняется.
    • (С ) Согласованность. Транзакция переводит базу данных из одного согласованного (целостного) состояния в другое согласованное (целостное) состояние. Внутри транзакции согласованность базы данных может нарушаться.
    • (И ) Изоляция . Транзакции разных пользователей не должны мешать друг другу (например, как если бы они выполнялись строго по очереди).
    • (Д ) Долговечность . Если транзакция выполнена, то результаты ее работы должны сохраниться в базе данных, даже если в следующий момент произойдет сбой системы.

    Транзакция обычно начинается автоматически с момента присоединения пользователя к СУБД и продолжается до тех пор, пока не произойдет одно из следующих событий:

    • подана команда COMMIT (зафиксировать транзакцию);
    • подана команда ROLLBACK (откатить транзакцию);
    • произошло отсоединение пользователя от СУБД;
    • произошел сбой системы.

    Свойства АСИД транзакций не всегда выполняются в полном объеме. Особенно это относится к свойству И (изоляция). В идеале, транзакции разных пользователей не должны мешать друг другу, т.е. они должны выполняться так, чтобы у пользователя создавалась иллюзия, что он в системе один. Простейший способ обеспечить абсолютную изолированность состоит в том, чтобы выстроить транзакции в очередь и выполнять их строго одну за другой. Очевидно, при этом теряется эффективность работы системы. Поэтому реально одновременно выполняется несколько транзакций (смесь транзакций ). Различается несколько уровней изоляции транзакций. На низшем уровне изоляции транзакции могут реально мешать друг другу, на высшем - они полностью изолированы. За большую изоляцию транзакций приходится платить большими накладными расходами системы и замедлением работы. Пользователи или администратор системы могут по своему усмотрению задавать различные уровни изоляции всех или отдельных транзакций. Более подробно изоляция транзакций рассматривается в п. 4.6.3.


    Свойство Д (долговечность) также не является абсолютными свойством, т.к. некоторые системы допускают вложенные транзакции. Если транзакция Б запущена внутри транзакции А, и для транзакции Б подана команда COMMIT, то фиксация данных транзакции Б является условной, т.к. внешняя транзакция А может откатиться. Результаты работы внутренней транзакции Б будут окончательно зафиксированы только, если будет зафиксирована внешняя транзакция А.

    Свойство (С) - согласованность транзакций определяется наличием понятия согласованности базы данных. База данных находится в согласованном (целостном) состоянии , если выполнены (удовлетворены) все ограничения целостности, определенные для базы данных.

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

    Примерами ограничений целостности могут служить следующие утверждения:

    Пример 4.62 . У каждого заказчика только один продавец.

    Пример 4.63 . Каждый сотрудник имеет уникальный табельный номер.

    Пример 4 .64 Сотрудник обязан числиться в только одном отделе.

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

    Как видно из этих примеров, некоторые из ограничений целостности являются ограничениями реляционной модели данных (см. гл. 3). Пример 4.63 представляет ограничение, реализующее целостность сущности. Примеры 4.62, 4.64 представляют ограничения, реализующие ссылочную целостность. Другие ограничения являются достаточно произвольными утверждениями, утверждениями связанными с правилами в конкретной предметной области (пример 4.65). Любое ограничение целостности является семантическим понятием, т.е. появляется как следствие определенных свойств объектов предметной области и/или их взаимосвязей.

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

    1. Отказ выполнить "незаконную" операцию.
    2. Выполнение компенсирующих действий.

    Работа системы по проверке ограничений изображена на рисунке 4.1.

    Каждая система обладает своими средствами поддержки ограничений целостности. Ограничения целостности классифицируются несколькими способами:

    • по способам реализации ;
    • по времени проверки ;
    • по области действия .

    По способам реализации различают:

    • декларативную поддержку ограничений целостности - средствами языка определения данных (DDL);
    • процедурную поддержку ограничений целостности - посредством триггеров и хранимых процедур.

    Рисунок 4.1 Работа системы по проверке ограничений

    По времени проверки ограничения делятся на:

    • немедленно проверяемые ограничения ;
    • ограничения с отложенной проверкой .

    По области действия ограничения делятся на:

    • ограничения домена ;
    • ограничения атрибута ;
    • ограничения кортежа ;
    • ограничения отношения ;
    • ограничения базы данных .

    Стандарт языка SQL поддерживает только декларативные ограничения целостности, реализуемые как:

    • ограничения домена;
    • ограничения, входящие в определение таблицы;
    • ограничения, хранящиеся в базе данных в виде независимых утверждений (assertion).

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

    Стандарт SQL не предусматривает процедурных ограничений целостности, реализуемых при помощи триггеров и хранимых процедур. В стандарте SQL 92 отсутствует понятие «триггер», хотя триггеры имеются во всех промышленных СУБД SQL-типа. Таким образом, реализация ограничений средствами конкретной СУБД обладает большей гибкостью, нежели с использованием исключительно стандартных средств SQL.