2013-02-16 7 views
5

Siamo di recente di fronte a un problema con inserimenti simultanei in una delle nostre tabelle sal server da più client. Spero che voi ragazzi possiamo aiutarci.SQL Server - Inserimenti simultanei alla tabella da più client - Verifica limite e blocco

Stiamo utilizzando la stored procedure per eseguire le transazioni. In quella stored procedure, per ogni transazione, calcoliamo le vendite totali finora. Se le vendite totali sono inferiori al limite impostato, , la transazione sarà consentita. In caso contrario, la transazione verrà negata.

funziona bene la maggior parte delle volte. Tuttavia, a volte quando più client tentano di eseguire la transazione esattamente nello stesso momento, il controllo dei limiti non riesce poiché entrambe le transazioni vengono eseguite.

Potete suggerire ragazzi come possiamo applicare efficacemente il limite tutto il tempo? C'è un modo migliore per farlo?

Grazie!

+1

Fornire la struttura della tabella e i dati di esempio. Il limite impostato è costante per tutte le transazioni? –

+0

Per intuizione, il problema potrebbe essere risolto se la procedura memorizzata viene eseguita molto più velocemente. Con una stored procedure di 100ms le collisioni saranno estremamente rare. Se pubblichi la query e la definizione della tabella, potremmo suggerire un indice che rende il calcolo totale molto veloce. – Andomar

+0

si prega di trovare la struttura della tabella. In questa somma (puntata) per ogni numero di puntata non deve essere superiore a 1000. Questo limite 1000 è memorizzato in un'altra tabella. \t [SlipID] [bigint] IDENTITY (1,1) NOT NULL, \t [TillID] [int] NOT NULL, \t [codice a barre] [varchar] (30) NOT NULL, \t [GamingDate] [data] NON NULL, \t [DrawID] [int] NOT NULL, \t [BetNumber] [tinyint] NOT NULL, \t [currencyID] [int] NOT NULL, \t [Puntata] [decimale] (9, 2) NOT NULL , \t \t [SlipTime] [datetime] NOT NULL, – sammy

risposta

5

Non penso sia possibile farlo in modo dichiarativo.

Se tutti gli inserti sono garantiti per passare attraverso la stored procedure e la SaleValue non viene aggiornato una volta inserito quindi il seguente dovrebbe funzionare (ho fatto i nomi di tabella e colonna in quanto questi non sono stati forniti nella domanda iniziale)

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 

il HOLDLOCK dà semantica serializable e blocca l'intero intervallo corrispondente al TransactionId e UPDLOCK impedisce due operazioni simultanee di bloccaggio stesso intervallo riducendo così il rischio di deadlock.

Un indice su TransactionId,SaleValue sarebbe meglio per supportare questa query.

+1

+1 intelligente! Forse un po 'troppo intelligente, in quanto solleva la barra per chiunque modifichi il codice. Potrebbe essere una buona idea chiudere la transazione prima che la procedura ritorni. – Andomar

+0

@Andomar - Grazie. Dimenticato! –

+0

Grazie Martin! Ha aiutato ... Tuttavia, abbiamo continuato a creare tabelle di riepilogo con valore totale più o meno per ogni transazione.Inoltre, le tabelle di vendita sono enormi e ogni volta che si effettua una query sulla tabella per calcolare la somma totale è necessario tempo perché troppi inserti e indici vengono frammentati troppo velocemente .. quindi, abbiamo deciso di avere quella tabella di riepilogo ... Finora, il suo aiuto ... Grazie! – sammy

Problemi correlati