2009-10-28 5 views
1

Bonjour J'ai peur de la simultanéité sur l'application partenaire car elle a eu des problèmes avec les opérations CRUDS ces derniers jours, en particulier avec les insertions. Alors j'ai couru SQL Profiler et notez que son instruction d'insertion ne pas user de transaction et aussi qu'il utilise:Sélectionnez MAX (champ) +1 DE ... Problèmes de simultanéité

INSERT INTO TABLEA VALUES ((SELECT MAX(NUMBERFIELD) +1 FROM TABLEA), ....); 

Comment éviter l'utilisation de MAX() + 1 pour générer des clés primaires? Je suggère d'utiliser autoincrement ou des champs de transaction, mais il ne veut pas ou peut-être qu'il ne sait pas comment y parvenir, y at-il une autre façon de mener avec cela?

Utilisation de SQL et 1.1

C++ * Son mon code, mais je pourrais envisager montrer ce post pour lui parce que je pense qu'il faut considérer que toutes les opinions sont les bienvenus. :)

+0

L'équivalent SQL Server de l'auto-incrémentation de MySQL s'appelle ** IDENTITY **: http://msdn.microsoft.com/en-us/library/aa933196%28SQL.80%29.aspx –

Répondre

3

Si vous le code correctement, vous devriez être en mesure d'obtenir la même concurrence de ce que avec une solution d'identité. Ce n'est pas intuitif. on pourrait penser que le verrouillage réduirait la concurrence. Mais j'ai couru plusieurs tests avec cinq connexions distinctes martelant la table, et prouvé à moi-même que le tour MAX + 1 effectué à peu près exactement la même chose que l'identité. Vous pouvez voir la discussion dans la première section du poste de blog suivant: modèle

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/bad-habits-to-kick-expecting-identity-to-mean-something.aspx

Quoi qu'il en soit voici la syntaxe que je recommande (je ne fais pas vraiment confiance les INSERT ... VALUES (sous-requête), désolé):

DECLARE @NextID INT; 

    BEGIN TRANSACTION; 

    SELECT @NextID = COALESCE(MAX(NumberColumn), 0) + 1 
     FROM dbo.TableA WITH (UPDLOCK); 

    INSERT dbo.TableA SELECT @NextID; 

    COMMIT TRANSACTION; 

vous devez imaginer les parties de traitement des erreurs (omis par souci de concision) mais je pense que vous aurez la dérive.

Bien sûr, ne prenez pas cela pour l'Évangile. Vous devrez exécuter des tests sur votre matériel à l'aide de vos données et de vos modèles d'accès pour déterminer si la concurrence risque d'être compromise par cette méthode. Cela pourrait très bien être l'une de ces réponses "ça dépend".

+0

thx pour un bon article) –

3

Avez-vous envisagé de créer la colonne de clé primaire IDENTITY? Il va faire de SQL Server génère automatiquement des valeurs pour la colonne:

CREATE TABLE Test (
    Id int identity primary key not null 
    -- ... 
) 
+0

D'accord! Beaucoup de gens utilisent le truc MAX + 1 parce qu'ils croient que cette colonne a un sens magique et qu'il ne peut y avoir de lacunes. Il y a certaines exigences d'affaires où cette séquence-sans-lacunes est une nécessité, mais je pense qu'ils sont rares et éloignés (par exemple, les entreprises qui génèrent des numéros de facture à partir de ce type de colonne). –

+0

Aaron: Il est ironique que 'MAX() + 1 ne fournisse pas non plus cette exigence de nombre de conséquences. Vous pouvez toujours avoir des trous si vous supprimez une ligne (sauf la dernière). –

+0

Cela est vrai, mais lorsque l'exigence est un besoin commercial réel, il y aura probablement un déclencheur empêchant la suppression, et une méthode de "suppression douce" - où la ligne est marquée comme "supprimée" mais n'est pas vraiment supprimée , peut-être juste n'est plus exposé à l'extrémité avant. –

Questions connexes