Zablokuj UTWÓRZ TABELĘ

19

W innej aplikacji zostałem dotknięty złym projektem: wiele wątków wykonuje EnsureDatabaseSchemaExists()jednocześnie metodę, która wygląda tak:

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

    CREATE TABLE MyTable ( ... );

END

Jednak nawet jeśli zostanie wykonany w transakcji SERIALIZABLE, kod ten nie wydaje się być bezpieczny dla wątków (tzn. Kod równoległy próbuje utworzyć tabelę wiele razy). Czy jest jakaś szansa, aby zmusić instrukcję SELECT do uzyskania blokady, która uniemożliwia innemu wątkowi wykonanie tej samej instrukcji SELECT?

Czy istnieje lepszy wzorzec dla metod wielowątkowych-ZapewnijSchemaExists ()?

DR
źródło

Odpowiedzi:

18

Najlepiej jest użyć jawnej transakcji zawierającej i uzyskać niestandardową blokadę wyłączności w celu ochrony całej operacji ( SELECTi CREATE TABLE) za pomocą sp_getapplock . Obiekty systemowe nie uwzględniają żądań poziomu izolacji i używają blokad w taki sam sposób, jak tabele użytkowników, zgodnie z projektem.

Warunkiem wyścigu w oryginalnym kodzie jest to, że wiele wątków może stwierdzić, że tabela nie istnieje, zanim jakikolwiek wątek dotrze do CREATE TABLEinstrukcji.

Paul White mówi GoFundMonica
źródło
6
+1, po prostu upewnij się, że applock otacza czek SELECT . W przeciwnym razie wprowadzisz impasy. Idealnie byłoby dostać blokadę aplikacji w trybie S, sprawdź, uaktualnienie do X, ale to jest trudne (co najmniej ...). Najbezpieczniejszą opcją jest zdobycie X, a następnie wykonanie całego wdrożenia schematu DB. Powinno to być rzadkie działanie (np. Podczas uruchamiania aplikacji), więc blokada X nie powinna mieć tak wielkiego znaczenia.
Remus Rusanu,
12

Radzę, aby spróbować / złapać jak najlepiej. Postępuj odpowiednio z duplikatem sprawy, np. zignoruj ​​to...

Prawdziwe pytanie: dlaczego DDL działa na żądanie z wielu xactów? Zwykle aktualizacja i migracja to poważna sprawa, obsługiwane w dedykowanych oknach czasowych ... Nie chcesz, aby migracja (najpierw kod?) Nieoczekiwanie się rozpoczęła, niektóre z tych kroków aktualizacji mogą zająć wiele godzin na dużym stole (rozmiar Operacje na danych ...)

Remus Rusanu
źródło
3
Kod jest rodzajem DatabaseLogger, który tworzy tabele na żądanie. Bez migracji, bez śmiesznego biznesu. Masz jednak całkowitą rację. Zamierzam odpowiednio zmienić kod.
DR
4
Weź również pod uwagę, że wdrożenie / konfiguracja jest całkowicie OK do uruchomienia w kontekście podwyższonych uprawnień (np. Przez administratora), ale normalne operacje nie. Obecnie potrzebujesz CREATE TABLEdotacji na normalne operacje ...
Remus Rusanu