Kilit Oluşturma Tablosu


19

Başka bir uygulamada kötü tasarım tarafından vuruldum: birden çok iş parçacığı EnsureDatabaseSchemaExists()temelde şuna benzeyen bir yöntemi aynı anda yürütür :

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

    CREATE TABLE MyTable ( ... );

END

Ancak, bir SERIALIZABLE işleminde yürütülse bile, bu kod iş parçacığı için güvenli gibi görünmüyor (yani paralel kod tabloyu birden çok kez oluşturmaya çalışır). SELECT deyimini, başka bir iş parçacığının aynı SELECT deyimini yapmasını engelleyen bir kilit almaya zorlama şansı var mı?

Multi-threaded-EnsureSchemaExists () yöntemleri için daha iyi bir model var mı?

Yanıtlar:


18

En iyi bahis, açık bir içeren işlem kullanmak ve tüm işlemi ( SELECTve CREATE TABLE) sp_getapplock kullanarak korumak için özel bir özel kilit elde etmektir . Sistem nesneleri, yalıtım düzeyindeki istekleri dikkate almaz ve kilitleri tasarım olarak kullanıcı tablolarıyla aynı şekilde kullanır.

Orijinal koddaki yarış koşulu, herhangi bir iş parçacığı CREATE TABLEifadeye kadar ulaşmadan önce birden çok iş parçacığının tablonun var olmadığı sonucuna varabilmesidir.


6
+1 yalnızca uygulama kilidinin SELECT kontrolünü tamamladığından emin olun . Aksi takdirde kilitlenme ortaya çıkarırsınız. İdeal olarak, S modunda uygulama kilidini alabilir, kontrol edin, X'e yükseltme yapın, ancak bu zor (en azından ...). En güvenli seçenek X'i elde etmek, ardından tüm DB şema dağıtımını yapmaktır. Nadir bir işlem olmalıdır (örn. Uygulama başlangıcında), bu nedenle X kilidi o kadar önemli olmamalıdır.
Remus Rusanu

12

Benim tavsiye denemek / yakalamak için en iyi çaba yapmak olacaktır. Yinelenen vakayı, uygun şekilde, ör. boşver...

Asıl soru: DDL neden birden çok xact'ten istek üzerine çalışıyor? Normalde yükseltme ve taşıma, özel zaman pencerelerinde işlenen ciddi bir konudur ... Taşıma işleminizin (önce kod?) Beklenmedik bir şekilde başlamasını istemezsiniz, bu güncelleme adımlarından bazıları büyük bir tabloda (boyut- -veri işlemleri ...)


3
Kod, istek üzerine tablolarını oluşturan bir tür DatabaseLogger'dır. Göç yok, komik iş yok. Ancak, tamamen haklısın. Kodu uygun şekilde yeniden düzenleyeceğim.
DR

4
Ayrıca, yükseltilmiş bir ayrıcalık bağlamında (örneğin, bir yönetici tarafından) çalıştırmak için dağıtımın / kurulumun mükemmel bir şekilde uygun olduğunu düşünün, ancak normal ops değildir. Şu anda CREATE TABLEnormal operasyonlar için hibe ...
Remus Rusanu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.