2013-02-16 18 views
5

Geçenlerde birden fazla müşteri bizim sal sunucu tablolardan birinin içine eşzamanlı uçlar ile bir durumla karşı karşıyadır edin. Umarım bize yardımcı olabilirsiniz.SQL Server - birden fazla istemciden masaya Eşzamanlı Uçlar - Sınır ve Block

Biz işlemlerini yapmak saklı yordam kullanıyor. Bu saklı yordamda, her işlem için, toplam satışları şimdiye kadar hesaplıyoruz. Toplam satışlar belirlenen limitin altındaysa, ise işleme izin verilir. Aksi halde işlem reddedilir. Çoğu zaman iyi çalışıyordur. Ancak, bazen birden fazla müşteri işlemi aynı anda yapmaya çalışırken, her iki işlem de gerçekleştikçe limit kontrolü başarısız oluyor.

siz etkili bir sınırı her zaman zorlamak nasıl önerebilir misiniz? Bunu yapmanın daha iyi bir yolu var mı?

Teşekkürler!

+1

Lütfen tablo yapınızı ve örnek verilerinizi sağlayın. Tüm işlemler için belirlenen limit sabit mi? –

+0

Bir öbek olarak, saklı yordamı çok daha hızlı çalıştırırsanız sorun çözülebilir. 100 ms saklanan prosedürle çarpışmalar çok nadir olacaktır. Sorgu ve tablo tanımını gönderirseniz, toplam hesaplamayı çok hızlı yapan bir dizin önerebiliriz. – Andomar

+0

tablo yapısını bulabilirsiniz. Her bir bahis numarasına ilişkin bu tutar (bahis) 1000'i geçmemelidir. Bu 1000 sınır başka bir tabloda saklanır. \t [SlipID] [Bigint] KİMLİK (1,1), BOŞ \t [TILLID] [int] NULL, \t [Barkod] [varchar] (30), NULL, \t [GamingDate] [tarih] değil değil NULL, \t [DrawID] [int] NULL, \t [BetNumber] [tinyint] NULL, \t [CurrencyID] [int] NULL, \t [Miktar] [ondalık] (9, 2) NULL , \t \t [SlipTime] [datetime] NOT NULL, – sammy

cevap

5

Ben bildirimli bunu yapmak mümkün olduğunu düşünmüyorum. (Bu başlangıç ​​söz konusu sağlanmayan gibi tablo ve sütun adlarını oluşan) tüm ekler saklı yordam geçmesi garanti edilir ve SaleValue kez ardından takılan güncelleme değildir çalışmalıdır aşağıdaki Eğer

DECLARE @SumSaleValue MONEY 

BEGIN TRAN 

SELECT @SumSaleValue = SUM(SaleValue) 
FROM dbo.Orders WITH (UPDLOCK, HOLDLOCK) 
WHERE TransactionId = @TransactionId 

IF @SumSaleValue > 1000 
    BEGIN 
    RAISERROR('Cannot do insert as total would exceed order limit',16,1); 
    ROLLBACK; 
    RETURN; 
    END 

/*Code for INSERT goes here*/ 

COMMIT 

HOLDLOCK, seri hale getirilebilir semantikler verir ve TransactionId ile eşleşen tüm aralığı kilitler ve UPDLOCK aynı anda kilitlenen iki eşzamanlı işlemi engeller ve böylece kilitlenme riskini azaltır.

TransactionId,SaleValue üzerine bir indeks bu sorguyu desteklemek için iyi olurdu.

+1

+1 Zeki! Belki biraz fazla zeki, kodu düzenleyen herkes için çıtayı yükseltir. Prosedür geri dönmeden önce işlemi kapatmak için iyi bir fikir olabilir. – Andomar

+0

@Andomar - Teşekkürler. Unut bunu! –

+0

Teşekkürler Martin! Bu yardımcı oldu ... Ancak, her işlem için toplam değer artı veya eksi ile özet tablolar oluşturmak için devam ettik.Ayrıca, satış tabloları çok büyük ve her seferinde toplam toplamı hesaplamak için tablonun sorgulanması çok fazla zaman ekledikçe ve indeksler çok hızlı parçalanmaya başladı. Bu nedenle, bu özet masasına sahip olmaya karar verdik ... Şimdiye kadar, ... Teşekkürler! – sammy