Проектування блокувань в додатках

Окремо від блокувань SQL Server слід розглянути ще один повязане з цим питання Спосіб обробки блокувань в додатках і вирішення питань конкуренції в багатокористувацької середовищі виключно важливі як з точки зору роботи користувача, так і з точки зору цілісності даних

Реалізація оптимістичній блокування

У роботі з многопользовательским доступом існують два підходи: оптимістична і песимістична блокування Вибір будь-якої з них визначає конкретний метод програмування додатки

Під оптимістичній блокуванням розуміється те, що поки користувач працює з даними в формі, інші користувачі мають до них доступ Таким чином, в даному випадку, поки який-небудь користувач працює з даними в клієнтському додатку, ніякі блокування не застосовуються Блокування встановлюється тільки на час запису оновлень в базу Недоліком оптимістичній блокування є можливість появи втрачених оновлень

Песимістична блокування використовує інший підхід, подібний відомому закону Мерфі: Якщо неприємність може статися, вона трапляється. Коли користувач працює з будь-якими даними, в песимістичній схемою ці дані блокуються

У той час як песимістична блокування непогано проявляє себе в невеликих робочих групах в настільних базах даних, великі програми з архітектурою клієнт / сервер вимагають більш високого рівня конкуренції Якщо блокування SQL Server підтримується, поки користувач працює з даними в формі VB або Access, робота додатка буде необгрунтовано повільної

Краще всього використовувати схему оптимістичній блокування, використовуючи мінімальну гранулярность блокувань як метод запобігання втрачених оновлень

Втрачені поновлення

Втрачені поновлення мають місце в тому випадку, коли два користувачі редагують одну і ту ж рядок, зберігають її, і поновлення другого користувача заміщають собою поновлення перший Наведемо приклад

1 Якийсь Ваня відкрив у клієнтському додатку Visual Basic рядок товару з кодом 1001 На частку секунди SQL Server застосовує загальну блокування для вилучення даних у форму VB,

2 Таня також відкриває рядок товару з кодом 1001, використовуючи клієнтську програму

3 Обидва користувача – Ваня і Таня-вносять свої зміни в дані про товар 1001 Ваня виправляє опис товару, а Таня – його категорію

4 Ваня зберігає рядок на SQL Server Інструкція UPDATE замінює старе опис товару новим, введеним Ванею

5 Таня також клацає на кнопці збереження, і її дані також відправляються на сервер в інструкції UPDATE Категорія товару змінюється, але так як у формі Тані було старе опис товару, воно заміщає собою нове, збережене Ванею

6 Ваня виявляє помилку і на черговій нараді скаржиться віце-президенту компанії на ненадійність бази даних SQL Server

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

Мінімізація втрачених оновлень

Якщо додаток буде використовувати схему оптимістичних блокувань, спробуйте мінімізувати шанс виникнення втрачених оновлень, а також ефект, вироблений ними Для цього можна скористатися декількома методами

■ Нормалізуйте базу даних так, щоб вона містила довгі і вузькі таблиці Зменшуючи число стовпців у рядку, ви знижуєте ймовірність втрачених оновлень Наприклад, база даних OBXKites має окрему таблицю для цін Користувач може працювати з прайс-листом і при цьому ніяк не припинятися з користувачем, що змінює інші дані про товари

■ Якщо інструкція UPDATE створюється в клієнтському додатку, постарайтеся перевіряти зміни та оновлювати тільки ті стовпці, в яких вони були фактично виконані користувачем Використання цього методу дозволило б уникнути втрачених оновлень в наведеному вище прикладі з Ванею і Танею, а також у більшості інших практичних ситуацій В якості додаткового переваги скорочується трафік між клієнтом і сервером і завантаження сервера баз даних

■ Якщо схема оптимістичній блокування не дозволяє уникнути втрачених оновлень, слід використовувати принцип хто останній записав, той і правий . Незважаючи на те що в цьому випадку можуть виникати втрачені поновлення, журнал аудиту допоможе знизити їх ефект Переглядаючи поновлення, виконані з однією і тією ж рядком протягом хвилини, ви зможете легко відстежити всі зміни в даних

Запобігання можливості втрачених оновлень

Більш суворе рішення проблеми втрачених оновлень, ніж просто мінімізація їх ефекту, полягає у використанні методу відстеження версій Тип даних rowversion, в ранніх версіях SQL Server відомий як timestamp, автоматично присвоює нове значення полю при кожному оновленні рядка Порівнюючи значення rowversion під час відбору даних для оновлення зі значенням в момент збереження даних, можна передбачити втрату оновлень за допомогою найпростішого програмного коду

Метод відстеження версій може використовуватися в інструкціях SELECT і UPDATE Для цього в пропозицію WHERE потрібно додати значення rowversion

У наступному прикладі продемонстровано використання методики відстеження версій з використанням двох користувальницьких оновлень Обидва користувача в клієнтському додатку відкривають рядок з одним і тим же товаром Обидві інструкції SELECT витягують стовпці RowVersion і ProductName:

SELECT RowVersion, ProductName

FROM Product

WHERE ProductCode = 10 01

Буде отримано наступний результат:

RowVersion                   ProductName

0x0000000000000077 Basic Box Kite 21 inch

Обидва клієнтських програми заповнили форми витягнутими даними Один з користувачів відредагував назву товару на Оновлення Вані, і, коли він клацнув на кнопці збереження, клієнтське додаток виконало наступну інструкцію SQL:

UPDATE Product

SET ProductName = Оновлення Вані1

WHERE ProductCode = 1001

AND RowVersion = 0x0000000000000077

Як тільки сервер обробив оновлення Вані, він автоматично змінив значення RowVersion Перевіряючи знову рядок, Ваня може побачити свої оновлення:

SELECT RowVersion, ProductName FROM Product

WHERE ProductCode = 10 01

Результат наступний:

RowVersion                    ProductName

0x00000000000000B9 Оновлення Вані

Якщо процедура поновлення перевіряє, чи не вплинули на рядок чиїсь поновлення, вона може побачити, що зміни Вані були прийняті:

SELECT @@ROWCOUNT

В результаті буде отримано значення 1

Незважаючи на те що значення стовпця RowVersion було змінено, клієнтське додаток Тані не знає про це Коли Таня спробує зберегти свої зміни, її інструкція UPDATE не знайде рядків, що задовольняють критерієм:

UPDATE Product

SET ProductName = Оновлення Тані

WHERE ProductCode = 1001

AND RowVersion = 0x0000000000000077

Якщо процедура поновлення перевіряє, чи були змінені будь-які рядки, то вона побачить, що редагування, виконане Танею, було проігноровано:

SELECT @@ROWCOUNT

Результатом буде нуль

Цей метод може також бути впроваджений в додатки, керовані збереженими процедурами Збережені процедури fetch і get повертають значення rowversion поряд з іншими даними рядка Коли додаток VB готово до оновлення і викликає збережену процедуру, воно включає rowversion в якості одного з обовязкових параметрів Збережена процедура update може перевірити значення rowversion і відмовити коли два існуючих значення не збігаються Якщо ускладнити цей метод, то збережена процедура або клієнтський додаток може перевірити в журналі аудиту, чи не існує оновлень стовпців, які можуть призвести до втрати оновлень, і якщо це так, повідомити

про це останньому користувачеві в повідомленні про помилку

Джерело: Нільсен, Пол Microsoft SQL Server 2005 Біблія користувача : Пер з англ – М: ООО ІД Вільямс , 2008 – 1232 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*