УПРАВЛЕНИЕ ТРАНЗАКЦИЯМИ И БЛОКИРОВКАМИ В MS SQL SERVER Методические указания к выполнению практической работы по курсу «Современные технологии управления базами данных» для студентов направления 230400.62 очной, заочной и заочносокращенной форм обучения Цель работы – изучение механизма транзакций и контрольных точек, приобретение навыков управления транзакциями различных видов, а также ознакомление с физической и логической архитектурой журнала транзакций и способами восстановления баз данных. ОСНОВНЫЕ ПОНЯТИЯ Одним из способов повышения надежности работы системы MS SQL Server 2005 является применение встроенного в систему механизма транзакций и контрольных точек и умелое его управление. Транзакция – это одна или несколько последовательных команд языка Transact – SQL, образующих логически завершенный пакет и выполняемых как единое целое. Если по какой-либо причине хотя бы одна из команд пакета не выполняется, то происходит откат системы к состоянию, в котором она была до начала транзакции, и транзакция считается не выполненной. По умолчанию каждая команда выполняется как самостоятельная транзакция. При необходимости в пакете можно явно указать начало и конец транзакции. Обработка транзакций в любой системе управления базами данных должна производиться с соблюдением следующих правил – правил ASID (Atomicity, Consistency, Isolation и Durability): Atomicity – атомарность: выполняемые в транзакции изменения либо выполняются все, либо не выполняются вовсе; Consistency – согласованность: все данные после выполнения транзакции должны находиться в согласованном состоянии с соблюдением всех правил и ограничений целостности; Isolation – изолированность: различными одновременно изменения данных, выполняемых работающими транзакциями, должны быть изолированы; Durability – долговечность: после завершения транзакции ничто не может вернуть систему в состояние, в котором она была до начала транзакции (происходит фиксация транзакции). Транзакции должны как можно меньше включать команд и изменять минимум данных. Соблюдение этого требования позволит наиболее эффективным образом обеспечить одновременную работу с данными множества пользователей системы SQL Server 2005. Они определяются на уровне соединения с сервером. Поэтому при закрытии соединения происходит откат невыполненной транзакции, и ее нельзя выполнить позже после восстановления соединения. SQL Server 2005 поддерживает три вида определений транзакций: явное (транзакции определяются программистом, т.е. явно указывается начало и конец транзакции), неявное (без явного указания начала и конца транзакции, они добавляются автоматически, например, при выполнении оператором update обновления нескольких полей), автоматическое (транзакция автоматически подтверждается после своего выполнения). Возможности изолированности транзакций определяются уровнями изолированности: 1) чтение неподтвержденных данных (нефиксированное чтение) – транзакции не изолированы, может считываться неподтвержденный результат транзакции. 2) Фиксированное чтение (чтение подтвержденных данных) – устанавливаются блокировки при чтении данных. Этот уровень гарантирует, что не будут считаны данные, которые в этот момент изменяются, но еще не подтверждены. 3) Повторяющееся чтение – блокируются все данные, которые используются транзакцией. 4) Упорядочиваемый – транзакции не выполняются одновременно, одна следует за другой. Для управления явными транзакциями применяют команды: BEGIN TRANSACTION – начало транзакции; COMMIT TRANSACTION – конец транзакции; ROLLBACK TRANSACTION – откат транзакции; SAVE TRANSACTION – создает точку сохранения в теле транзакции для того, чтобы можно было выполнить откат до ее состояния. Во всех трех командах допускается использование сокращения TRAN вместо слова TRANSACTION. Можно указывать имя транзакции или имя переменной строкового типа, которой присваивается имя транзакции, что позволяет ссылаться на эту транзакцию когда выполняется ее подтверждение или откат. BEGIN TRAN <имя транзакции или имя локальной переменной> [WITH MARK] Дополнительный аргумент WI T H M A R K позволяет специальным образом маркировать транзакцию в журнале транзакций, что используется при восстановлении базы данных. Пример 1 BEGIN TRAN INSERT INTO Postavka VALUES (getdate()) INSERT INTO Postavka VALUES (’12.12.2009’) IF (@@error = 0) BEGIN COMMIT TRAN END ELSE BEGIN PRINT ‘возникла ошибка’ ROLLBACK TRAN END Пример 2 BEGIN TRAN INSERT INTO Postavka VALUES (getdate()) SAVE TRAN INSERT INTO Postavka VALUES (’12.12.2009’) IF (@@error = 0) BEGIN COMMIT TRAN END ELSE BEGIN PRINT ‘возникла ошибка’ ROLLBACK TRAN END Транзакции могут быть вложенными Пример 3 BEGIN TRAN UPDATE Titles SET prise = 20 WHERE Title_id = 125 BEGIN TRAN UPDATE Titles SET type = ‘potboiler’ WHERE Title_id = 125 COMMIT TRAN Блокировки и взаимоблокировки В многопользовательских средах обработки данных при одновременном чтении и изменении пользователями могут одних и возникнуть тех же данных следующие несколькими четыре проблемы одновременного доступа: The Lost Update заключающаяся в Problem – том, что проблема последнего изменения, если несколько пользователей будут одновременно изменять одни и те же данные, то сохраняться изменения того пользователя, который запишет их последним; для решения этой проблемы надо обеспечить последовательное внесение изменений. The Uncommitted Dependency Problem – проблема грязного чтения, когда пользователь считывает данные, обработка которых еще не завершена другим пользователем; для ее решения необходимо ожидание окончания всех изменений данных. The Inconsistent Analysis Problem – проблема не повторяемого чтения, когда требуется многократное чтение одних и тех же данных, а они изменяются в это время другим пользователем; для ее решения необходим запрет на изменение таких данных другими пользователями. The Phantom Read Problem – проблема чтения фантомов, когда один пользователь выбирает данные из таблицы, а второй пользователь вставляет новые строки; здесь также необходим запрет на изменение данных вторым пользователем. Временно накладываемые ограничения на выполнение некоторых операций обработки данных называются блокировками (locks). SQL Server 2005 поддерживает различные уровни блокирования объектов, начиная с отдельной строки и заканчивая базой данных в целом: RID – на уровне строки таблицы при вставке новых строк; Key – на уровне индекса, когда блокируется его часть, соответствующая изменяемым в транзакции данным; Page – на уровне страницы; Extent – на уровне экстента; Table – на уровне таблицы; DB – на уровне базы данных. В зависимости от выполняемых над данными действий SQL Server обеспечивает пять типов блокировок: Пессиместичная – блокировка применяется только на время изменения данных и снимается сразу после того, как изменения завершены. Такой режим гарантирует, что никакой другой пользователь не изменяет данные в это же время. Оптимистическая блокировка – применяется только когда данные изменены и записываются (на время COMMIT TRAN) Блокировка с обеспечением совместного доступа – коллективная блокировка при чтении данных несколькими пользователями, позволяет параллельно выполняющимся транзакциям считывать ресурс, в это время никакая другая транзакция не может изменить данные; Блокировка применяется, с если обеспечением транзакция взаимоисключающего изменяет данные. доступа Гарантирует, – что множественные изменения не могут быть одновременно выполнены в одном и том же ресурсе. Блокировка при обновлении данных – блокировка массового обновлении при выполнении операций массового копирования в таблицу. Управлением блокировками занимается менеджер блокировок (lock manager), контролирующий их наложение и разрешение конфликтов. Блокировки и транзакции тесно связаны друг с другом. Транзакции накладывают блокировки на данные, так что пользователю чаще всего не нужно предпринимать никаких действий по управлению блокировками. Однако при необходимости в запросе можно явно указать, какой тип блокировки надо использовать в том или ином случае. Взаимоблокировка- ситуация, когда два пользователя (или сеанса) устанавливают блокировки на различные объекты и каждому пользователю нужно установить блокировку на объект, уже блокированный другим пользователем. SQL Serverавтоматически исправляет ситуации взаимоблокировки, выбирая одно из приложений и принуждая его снять свою блокировку. Регулировка приоритета транзакций С помощью команды SET DEADLOCK_PRIORITY (аргументы) можно установить приоритет транзакции. Аргументы: LOW - Определяет, что текущий сеанс более предпочтительней в качестве «жертвы» взаимоблокировки. NORMAL - Определяет, что сеанс возвращается к методу обработки взаимоблокировок, принятому по умолчанию. Инструкция SET LOCK_TIMEOUT (время) Определяет время в миллисекундах, в течение которого сервер ждет снятия блокировок. ИНДИВИДУАЛЬНЫЕ ЗАДАНИЯ В базе данных, созданной на лабораторной работе №1, 2 создайте транзакции.