10 июня 2012 г.

Управление транзакциями в Microsoft SQL Server 2008


Сегодня мы обсудим одно из фундаментальных понятий в SQL Server 2008 – транзакции. Транзакции позволяют управлять набором команд, которые выполняются в базе данных, как единым целым. Использование транзакции предоставляют разработчику следующие преимущества:
  1. Если две команды работают внутри одной транзакции – то будут выполнены обе команды, либо ни одной;
  2. Если какая-либо команда внутри транзакции завершится с ошибкой – все команды транзакции будут отмены и данные вернутся в то состояние, в каком они были до начала транзакции;
  3. Во время выполнения транзакции данные могут оставаться изолированными и недоступными для других транзакций;
  4. После успешного выполнения команды фиксации транзакции данные гарантированно сохранятся в базе.
Грамотное использование транзакции является залогом успешной разработки баз данных. Транзакции в Microsoft SQL Server могут быть двух типов: явные и неявные. Явные транзакции определяет разработчик, в соответствии с личными нуждами, при выполнении запросов или в тексте хранимых процедур. Неявные транзакции создаются автоматически и управляются средой SQL Server. Например, неявные транзакции создаются при выполнении каждой команды INSERT, UPDATE или DELETE.
Явные транзакции определяются при помощи следующей команды:
BEGIN TRANSACTION [ @transactionName ]
Имя транзакции указывать не обязательно. Чтобы зафиксировать изменения, которые выполнились внутри транзакции к определенному моменту, используется команда:
COMMIT TRANSACTION [ @transactionName ]
Чтобы отменить изменения, внесенные в базу командами транзакции, используйте команду:
ROLLBACK TRANSACTION [ @transactionName ]
Эти три команды являются базовыми блоками управления транзакциями. Транзакции могут быть вложенными друг в друга. В таком случае рекомендуется давать имя каждой транзакции и использовать его во всех командах, чтобы получить ожидаемое поведение. К примеру, команда ROLLBACK без имени транзакции, на каком уровне вложенности она бы не находилась, всегда будет откатывать самую верхнюю транзакцию.
Также возможно создание временных точек сохранения прогресса внутри транзакции. При наличии таких точек транзакцию можно будет откатить не полностью, а до последней контрольной точки, что является достаточно удобным механизмом во многих ситуациях. Сохранить контрольную точку в транзакции можно при помощи следующей команды:
SAVE TRANSACTION
Теперь, в случае отката транзакции, будут отменены только те команды, которые находятся в коде между командами SAVE TRANSACTION и ROLLBACK.
Какие могут возникнуть проблемы при использовании транзакций:
  1. Чтение «грязных» данных (чтение незафиксированных данных) – такая ситуация происходит, когда одна транзакция обновляет данные в таблице, а другая, в тоже время, пытается эти данные считать. Если при этом первая транзакция отменит операцию обновления, то черновые данные по-прежнему останутся во второй транзакции;
  2. Повторное чтение строк – допустим, работают параллельно две транзакции. Первая транзакция считывает набор данных. Вторая транзакция обновляет эти данные и фиксирует изменения. Первая транзакция повторно считывает данные, которые теперь не совпадают с результатами первого запроса;
  3. Фантомные строки – данная ситуация происходит когда одна транзакция считывает набор данных, а вторая одновременно вносит изменения в тот же набор данных. В результате первая транзакция может получить часть новых строк (обновленных) и часть старых строк (до которых вторая транзакция еще не успела дойти).
Разумеется, что не для всех систем данные ситуации являются критичными. Поэтому решение о защите базы от этих ситуаций принимается в каждом случае индивидуально.
Для предотвращения приведенных выше ситуаций средой SQL Server предусмотрено такое понятие, как уровень изоляции транзакции. Данное понятие определяет для среды выполнения правила взаимодействия транзакций между собой. Существует 5 типов изоляции:
  1. READ UNCOMMITTED – не накладывает никаких ограничений на взаимодействие транзакций. В этом режиме возможно появление всех приведенных выше ситуаций. Обеспечивает лучшую производимость и максимальный параллелизм;
  2. READ COMMITTED – режим по умолчанию, разрешает транзакции считывать только зафиксированные данные. Предотвращает ситуацию чтения «грязных» данных;
  3. REPEATABLE READ – не позволяет считывание незафиксированных данных. Защищает от ситуаций чтения «грязных» данных и повторного чтения строк;
  4. SNAPSHOT – режим формирует моментальный снимок считываемых данных и передает его в транзакцию. Изменения, производимые другими транзакциями, в снимке не отображаются. Транзакция может изменять только снимок, а не реальные данные. Производительность режима оставляет желать лучшего. Специфический режим, используется крайне редко;
  5. SERIALIZABLE – полностью блокирует используемые данные, пока транзакция не закончится. Обеспечивает защиту от всех негативных ситуаций, однако обладает наихудшей производительностью, в связи с чем, не может использоваться в приложениях, активно использующих базу.
Установить уровень изоляции транзакции можно следующей командой:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Однако помните, что чем выше уровень изоляции вы установите, тем больший проигрыш в производительности получите. Поэтому необходимо внимательно относится к применению данной команды, анализируя требования системы.
SQL Server также предоставляет пользователя статистику транзакций. Например, узнать количество транзакций, которые являются активными в данном сеансе, можно посмотрев глобальную переменную @@trancount или запросить системное представление sys.dm_tran_current_transaction.
В данной статье мы познакомились с транзакциями в Microsoft SQL Server 2008. Узнали об их предназначении, способе использования, характерных проблемах и способах их решения. Здесь мы рассмотрели возможности управления транзакциями на уровне SQL Server. В следующей статье будет рассмотрено, каким образом можно управлять транзакциями из кода приложения.
Спасибо за внимание!

1 комментарий:

  1. Евгений, спасибо за труд! Лаконичное и доходчивое объяснение. Буду читать следующую Вашу статью.

    ОтветитьУдалить