SQL Server'a veri eklemek tüm tabloyu kilitliyor mu?
Entity Framework kullanıyorum ve blob alanını içeren veritabanımıza kayıtlar ekliyorum. Blob alanı 5 MB'a kadar veri olabilir.
bu tabloya bir kayıt takarken, tüm tabloyu kilitliyor mu?
bu nedenle, tablodaki herhangi bir veriyi sorgulıyorsanız, ekleme bitene kadar engelleyecek mi (bunun etrafında yollar olduğunu biliyorum, ancak varsayılan olarak konuşuyorum)?
nasıl bir kilitlenmeye neden olmadan önce ne kadar sürer? Bu süre, sunucuda ne kadar yük olduğuna bağlı mı, örneğin çok fazla yük yoksa, bir kilitlenmeye neden olmak daha uzun sürer mi?
herhangi bir zamanda neyin kilitlendiğini izlemek ve görmek için bir yol var mı?
her iş parçacığı tek tablolarda sorgular yapıyorsa, engelleme işleminin gerçekleşebileceği bir durum var mı? Yani bir kilitlenme yalnızca bir birleşim olan bir sorgu varsa oluşabilir bu durumda değil mi birden fazla tablo üzerinde hareket?
bu, kodumun çoğunun, uzun süren işlemlerin yığınları veya bunun gibi bir şey değil, sadece bir grup select ifadesi olduğunu dikkate alıyor.
4 ответов
Kutsal inek, burada bir sürü sorunun var, heh. İşte birkaç cevap:
bu tabloya bir kayıt takarken, tüm tabloyu kilitliyor mu?
varsayılan olarak değil, ancak TABLOCK ipucu kullanıyorsanız veya belirli türde toplu yük işlemleri yapıyorsanız, o zaman evet.
bu nedenle, tablodaki herhangi bir veriyi sorgulıyorsanız, ekleme bitene kadar engellenir (fark ettim bunun etrafında yollar var, ancak varsayılan olarak konuşuyorum)?
bu küçük bir hile alır. Birisi kilitli olduğunuz tablodaki bir sayfadan veri seçmeye çalışıyorsa, o zaman evet, onları engellersiniz. Bunun etrafında, select deyiminde NOLOCK ipucu gibi şeylerle veya Read Committed anlık görüntü İzolasyonunu kullanarak çalışabilirsiniz. İzolasyon seviyelerinin nasıl çalıştığına ilişkin bir başlangıç noktası için Kendra Little'ın izolasyon seviyelerine göz atın. .
bir kilitlenme neden önce ne kadar sürer? Bu süre, sunucuda ne kadar yük olduğuna bağlı mı, örneğin çok fazla yük yoksa bir kilitlenmeye neden olmak daha uzun sürer mi?
Deadlocks zamana dayanmıyor-bağımlılıklara dayanıyorlar. Bu duruma sahip olduğumuzu söyle:
- sorgu a bir sürü kilit tutuyor ve sorgusunu bitirmek için, o' s şeyler ihtiyacı var sorgu B tarafından kilitli
- sorgu B de bir sürü kilit tutuyor ve sorgusunu bitirmek için sorgusuyla kilitlenen şeylere ihtiyacı var
ne de sorgu ileriye doğru hareket edebilir (standoff'u düşünün), bu nedenle SQL Server bir beraberlik çağırır, birinin sorgusunu arkaya çeker, kilitlerini serbest bırakır ve diğer sorgunun devam etmesini sağlar. SQL Server bir geri almak için daha az pahalı olacak dayalı kurban alır. Eğer fantezi almak istiyorsanız, kullanabilirsiniz SET deadlock_priority kendi sırtında hedefleri boyamak için belirli sorguları düşük, ve SQL Server önce onları vuracaktır.
herhangi bir zamanda neyin kilitlendiğini izlemek ve görmek için bir yol var mı?
kesinlikle - sys gibi sorgulayabileceğiniz dinamik Yönetim görünümleri (Dmv'ler) var.dm_tran_locks, ama en kolay yolu Adam Machanic ücretsiz sp_WhoİsActive saklanan proc kullanmaktır . Bu gerçekten kaygan böyle çağırabileceğiniz sp_who'nun değiştirilmesi:
Her çalışan sorgu için
sp_WhoIsActive @get_locks = 1
, tuttuğu kilitlerin tümünü açıklayan küçük bir XML alırsınız. Ayrıca bir engelleme sütunu var, bu yüzden kimin kim olduğunu görebilirsiniz. Tutulan kilitleri yorumlamak için kitap online açıklamaları kilit türleri kontrol etmek isteyeceksiniz .
her iş parçacığı tek tablolarda sorgular yapıyorsa, o zaman bir durum var mı engelleme oluşabilir? Bu nedenle, bir kilitlenmenin yalnızca bir birleştirme özelliğine sahip ve birden fazla tablo üzerinde hareket eden bir sorgunuz varsa gerçekleşebileceği durum böyle değil mi?
ister inanın ister inanmayın, tek bir sorgu aslında kendisini kilitleyebilir ve evet, sorgular sadece bir masada kilitlenebilir. Deadlocks hakkında daha fazla bilgi edinmek için Jeremiah Peschka tarafından Deadlocks ile zorluk göz atın .
SQL üzerinde doğrudan kontrole sahipseniz, satır seviyesi kilitlemeyi kullanarak zorlayabilirsiniz:
INSERT INTO MyTable(Id, BigColumn) WITH (ROWLOCK) VALUES(...)
bu iki cevap yararlı olabilir:
management Studio'daki geçerli tutulan kilitleri görüntülemek için sunucunun altına bakın, ardından Yönetim / Etkinlik Monitörü. Nesne tarafından kilitler için bir bölüm vardır, bu yüzden ekler gerçekten bir soruna neden olup olmadığını görmek gerekir.
ile gelebileceğim en iyi cevap: bağlıdır.
kontrol etmenin en iyi yolu, bağlantı SPİD'İNİZİ bulmak ve kilit modunun SEKME türünde olup olmadığını kontrol etmek için sp_lock SPİD'İ kullanmaktır. Tablo adını
SELECT OBJECT_NAME(objid) ile de doğrulayabilirsiniz. Ayrıca kilitlemeyi kontrol etmek için aşağıdaki sorguyu kullanmak istiyorum.
SELECT RESOURCE_TYPE,RESOURCE_SUBTYPE,DB_NAME(RESOURCE_DATABASE_ID) AS 'DATABASE',resource_database_id DBID, RESOURCE_DESCRIPTION,RESOURCE_ASSOCIATED_ENTITY_ID,REQUEST_MODE,REQUEST_SESSION_ID, CASE WHEN RESOURCE_TYPE = 'OBJECT' THEN OBJECT_NAME(RESOURCE_ASSOCIATED_ENTITY_ID,RESOURCE_DATABASE_ID) ELSE '' END OBJETO FROM SYS.DM_TRAN_LOCKS (NOLOCK) WHERE REQUEST_SESSION_ID = --SPID here
SQL Server 2008'de (ve daha sonra) tablodaki kilit tırmanmasını devre dışı bırakabilir ve ınsert (ROWLOCK) ile zorlayabilirsiniz yan tümce etkili bir rowlock zorluyor. Bu, SQL Server 2008'den önce yapılamaz (ROWLOCK ile Yazabilirsiniz, ancak SQL Server yoksaymayı seçebilir).
burada generallerle konuşuyorum ve genellikle geliştiricilere, özellikle de 1 MB'den büyükse, onlardan kaçınmalarını tavsiye ettiğim için Lekelerle fazla tecrübem yok.