Блокування СТВОРИТИ ТАБЛИЦЮ


19

В іншому додатку мене вразив поганий дизайн: кілька потоків виконують EnsureDatabaseSchemaExists()метод одночасно, який в основному виглядає так:

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'MyTable') AND type = N'U') BEGIN

    CREATE TABLE MyTable ( ... );

END

Однак, навіть якщо він виконується в транзакції СЕРІАЛІЗАЦІЙНО, цей код не здається безпечним для потоків (тобто паралельний код намагається створити таблицю кілька разів). Чи є якийсь шанс змусити оператор SELECT придбати замок, який заважає іншому потоку виконувати той самий оператор SELECT?

Чи є краща модель для багатопотокових методів EnsureSchemaExists ()?

Відповіді:


18

Найкраще зробити ставку - використовувати явну транзакцію, що містить вміст, та придбати спеціальний ексклюзивний замок для захисту всієї операції ( SELECTта CREATE TABLE) за допомогою sp_getapplock . Системні об'єкти не задовольняють запити рівня ізоляції та використовують блокування так само, як і таблиці користувачів, за проектом.

Умова перегонів у вихідному коді полягає в тому, що декілька потоків можуть зробити висновок, що таблиця не існує до того, як жоден потік потрапляє до CREATE TABLEоператора.


6
+1 просто переконайтесь, що програма закриває чек ВИБІР . Інакше ви введете тупики. В ідеалі можна заблокувати додаток у режимі S, перевірити, оновлення до X, але це хитро (хоча б сказати ...). Найбезпечніший варіант - придбати X, а потім виконати всю розгортання схеми БД. Це має бути рідкісним варіантом (наприклад, при запуску програми), тому блокування X не повинно мати великого значення.
Рем Русану

12

Моя рекомендація полягає в тому, щоб зробити все можливе, щоб спробувати / зловити. Поводьтесь із дублікатом чітко, якщо це доречно, наприклад, ігноруйте це ...

Справжнє запитання: чому DDL працює за запитом від декількох xacts? Зазвичай оновлення та міграція є серйозною справою, яка обробляється у вікно, призначене для часу ... Ви не хочете, щоб ваша міграція (перше з коду?) Почалася несподівано, деякі з цих кроків оновлення можуть зайняти години за великим столом (розмір-of -дані операції ...)


3
Код - це якась DatabaseLogger, яка створює свої таблиці за запитом. Ні міграції, ні смішних справ. Однак ви абсолютно праві. Я збираюся переробити код відповідним чином.
ДР

4
Також врахуйте, що розгортання / налаштування цілком нормально для запуску в контексті підвищених привілеїв (наприклад, адміністратором), але звичайні операційні можливості це не так. Наразі Ви вимагаєте CREATE TABLEдотації для звичайних операцій ...
Ремус Русану
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.