мося до розподілених транзакціях. Докладніше про розподілених транзакціях написано в наступному розділі.
6. Управління розподіленими транзакціями
6.1 Запуск розподілених транзакцій
розподілених транзакцій в Transact-SQL можна запустити наступними способами:
. Явно почати розподілену транзакцію, використовуючи інструкцію BEGIN DISTRIBUTED TRANSACTION.
Наприклад, для зміни даних в таблиці Orders в розподіленої базі даних expert_db і її видаленої копії re_ex, виконаємо наступний запит:
expert_dbdistributed transaction; Orders set Supplier= Izmenen Where ID= 1 017 raquo ;; [ASH-PC] .re_ex.dbo.Orders set Supplier= Izmenen Where ID= 1 017 raquo ;; transaction;
Зверніть увагу, що шлях до таблиці, що знаходиться поза локальної копії бази даних, вказується повністю: ім'я сервера, ім'я віддаленої бази даних, ім'я таблиці. На малюнку 8 показаний ефект використання розподіленої транзакції. Тригери в базах, що виконують вибірку по всій таблиці, показують, що запит виконався в 2х базах даних.
. Перебуваючи в локальній транзакції, виконати розподілений запит. У цьому випадку транзакція автоматично буде розширена до розподіленою. В наведеному вище прикладі просто опустимо слово distributed , при цьому ефект від виконання запиту буде тим же.
Рисунок 8 - Робота розподіленої транзакції
6.2 Завершення транзакції
Щоб транзакція вважалася завершеною, після виконання всіх дій її потрібно застосувати інструкцією COMMIT TRANSACTION, або відкотити інструкцією ROLLBACK TRANSACTION. У першому випадку всі зміни збережуться в базі, у другому - скасовані.
У спробуємо відкотити і застосувати транзакцію:
expert_dbtransactionOrders set Customer= x Where ID= 1016 raquo ;; [ASH-PC] .re_ex.dbo.Orders set Customer= x Where ID= 1016 raquo ;; transactiontransactionOrders set Customer= z Where ID= 1 017 raquo ;; [ASH-PC] .re_ex.dbo.Orders set Customer= z Where ID= 1 017 raquo ;; transaction
В результаті виконання прикладу зміниться тільки рядок з ID 1017, оскільки зміни в рядку 1 016 ми відкотили.
6.3 Блокування
При виконанні транзакції, дані, які вона обробляє блокуються. Це відбувається для того, щоб під час виконання однієї транзакції, інша не змінила або не прочитавши дані, які змінені не до кінця, що може в свою чергу призвести до пошкодження набору даних, або до зчитування помилкових даних. Поки перша транзакція не буде завершена, друга буде очікувати моменту зняття блокування.
Виконаємо 2 запиту на виконання транзакцій. Для зручності створимо два вікна запиту з середовищі SQL Management Studio. Помістимо код транзакцій кожен у своє вікно.
- Транзакція 1
expert_db
BEGIN TRANSACTIONOrders SET Mass= +1000 WHERE ID= 1 008
- Транзакція 2
expert_dbTRANSACTIONOrders SET Distance= 100 WHERE ID= 1 008 TRANSACTION
По черзі виконаємо запити. Транзакція 2 буде очікувати виконання до тих пір, поки транзакція 1 не буде завершено процес або відвалений. Допишемо рядок COMMIT TRASACTION в перший запит, виконаємо його, і другий запит відразу ж виконається.
6.4 взаімоблокіровке
взаімоблокіровке називають особливу ситуацію, яка виникає тільки тоді, коли транзакції з безліччю завдань змагаються за ресурси один одного. Наприклад, перша транзакція встановила блокування ресурсу А, і їй необхідно заблокувати ресурс Б, а в цей же час друга транзакція, що заблокувала ресурс Б, потребує блокування ресурсу А.
Кожна з цих транзакцій очікує, поки інша зніме свою блокування, і жодна з них не може завершитися, поки цього не станеться. Якщо не відбудеться зовнішнього впливу або одна з транзакцій завершиться з певної причини (наприклад, за часом очікування), то ця ситуація може тривати нескінченно.
Раніше взаимоблокировки представляли собою серйозну проблему, але тепер SQL Server дозволяє успішно вирішити її.
6.4.1 Створення взаимоблокировки
Найпростіше створити ситуацію взаимоблокировки в SQL Server за допомогою двох підключень в редакторі запитів утиліти Management Studio. Перша і друга транзакції намагаються оновити одні й ті ж рядки, проте в протилежному порядку.
Помістимо код в перше вікно запиту і виконаємо його...