2009-06-15 12 views
6

Şu anda, bir SQL Server Tablo bir kayıt sokulması ve aşağıdaki gibi otomatik artış kimliği seçtikten ediyorum:Bir işlem içinde çalışırken aşağıdaki SQL Server neden kilitlenmiyor?

(@p0 int,@p1 nvarchar(8))INSERT INTO [dbo].[Tag]([Some_Int], [Tag]) 
VALUES (@p0, @p1) 

SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value] 

(Bu Linq SQL kullanılarak oluşturulan). TransactionScope nesnesini bir seri hale getirilebilen yalıtım düzeyi ile kullanan bir işlem içinde bu kodu çalıştırdığım için SQL Server bir kilitlenme hatası atar. Ben kilitlenme grafik olayları analiz ve ilgili iki süreç her aşağıdaki bilgileri anlamak gibi dönüştürme işlemi gerçekleştirmek için diğer yanda bekliyorlardı bulundu:

<resource-list> 
    <keylock hobtid="72057594101170176" dbid="5" objectname="foo.dbo.Tag" indexname="PK_Tag_1" id="lockb77cdc0" mode="RangeS-S" associatedObjectId="72057594101170176"> 
    <owner-list> 
    <owner id="processc9be40" mode="RangeS-S"/> 
    </owner-list> 
    <waiter-list> 
    <waiter id="processc9ae38" mode="RangeI-N" requestType="convert"/> 
    </waiter-list> 
    </keylock> 
    <keylock hobtid="72057594101170176" dbid="5" objectname="foo.dbo.Tag" indexname="PK_Tag_1" id="lockb77cdc0" mode="RangeS-S" associatedObjectId="72057594101170176"> 
    <owner-list> 
    <owner id="processc9ae38" mode="RangeS-S"/> 
    </owner-list> 
    <waiter-list> 
    <waiter id="processc9be40" mode="RangeI-N" requestType="convert"/> 
    </waiter-list> 
    </keylock> 
    </resource-list> 

Benim anlayış işlem kapsamı ikincisini önleyebileceği idi ilkini tamamlayana kadar eki gerçekleştirme işlemi, hem kimlik ekleme hem de seçme işlemini tamamladı. Ancak bu durum böyle görünmüyor. İplik güvenli bir şekilde istediğimi elde etmek için en iyi yaklaşıma kim ışık tutabilir? ;

- Sadece nota

- Güncelleme Ben her iki veritabanı arasında iletişim kurmak için yeni bir DataContext oluşturur gibi iki bağlantı arasında bir bağlantı paylaşılmadığından emin değilim.

- Yine Güncellendi -

Remus Rusanu bazı atlanmış bilgi sorunuyla ilgili olduğuna işaret etti, ben kilitlenme grafik rapora dayanarak senaryosunu basitleştirmek için denedim, ama açıklama uzattığımızı İşte. Ekleme yapmadan önce, etiketin zaten var olup olmadığını belirlemek için söz konusu tablodaki bir sorgu var. Eğer yaparsam işlemi bitiririm. Eğer eklenti devam etmiyorsa ve daha sonra, güncelleme son değişiklik yapılmış olsa da, birincil anahtar olarak Some_Int olan bir tabloda, burada gösterilmeyen bir güncelleme gerçekleştirmeliyim. Tag tablosunun hem auto inc ID hem de Some_Int'den oluşan kümelenmiş bir indekse sahip olması da önemli olabilir. Tabloyu değiştirmeyi denediğimden bu son bilgi parçasının alaka düzeyine ait olduğunu düşünmüyordum, çünkü sadece auto inc alanını birincil anahtar/kümelenmiş indeks olarak kullanmaktan vazgeçtim.

Teşekkürler.

+0

İyi bir soru! Bir cevap görmek istiyorum. – Chris

cevap

7

Söz konusu 'dönüştürme', herhangi bir şekilde 'CONVERT' işleviyle ilgili olmayan 'lock convert' from RangeS-S to RangeI-N'dur. Zaten PK_Tag_1 dizinine yerleştirilmiş RangeS-S kilitlerinizin olması, bir INSERT'den daha fazlasını yaptığınızı gösterir. İşleminiz, herhangi bir şans eseri, ekleme işlemine başlamadan önce yeni kaydın "var olup olmadığını" ilk kez kontrol ediyor mu?

+0

gerçekten de ... – LaserJesus

+0

benim kilitlenme sorunlarının hafifletilmesi gibi görünüyor daha tamamen – LaserJesus

+0

Ben yalıtım düzeyi anlık için değiştirdik durumu yansıtacak şekilde soru güncelledik. Yardımlarınız :) – LaserJesus

-1

Hiç bir işlem yapmanız gerekmez. scope_identity() işlevi, en son aynı kapsamda oluşturulan kimliği döndürecek, böylece başka bir kapsamda olduğu gibi, kimliği almadan önce başka bir ekleme çalıştırılırsa sorun olmaz.

+0

İşlem kapsamı, başka bir yerde bir şeyler yanlış giderse ya da en azından uni testi bittiğinde değişiklikleri geri alabilirim. – LaserJesus

+0

@downvoter: Neden düşüş yok? Düşündüğünüzü söylemezsen, cevabı hiçbir şekilde iyileştiremez. – Guffa

0

Sorgunuzda kullanılan isolationLevel öğesini kontrol edin. TransactionScope'un varsayılan olarak Serializable yalıtım düzeyini kullandığını unutmayın (http://msdn.microsoft.com/en-us/library/ms172152.aspx). İşleminizin tecrit düzeyini Komutu Oku'ya değiştirmeyi deneyin.