2009-06-24 5 views
0

J'ai une table qui contient le numéro de séquence.Ce verrouillage est-il correct?

Structure de la table

SequenceGenerator 
    Year int 
    Month int 
    NextNumber int 

Année + mois font clé primaire. La séquence est réinitialisée tous les mois. J'utilise Subsonic pour générer DAL. Pour obtenir le numéro de séquence suivant j'ai écrit une classe qui retourne le numéro suivant pour les demandeurs:

private static readonly object _lock = new Object(); 
private static readonly string FormatString = "{0}{1}{2}{3}"; 
private static readonly string NumberFormat = "000000"; 

public static object GetNextNumber(string prefix) 
{ 
    lock (_lock) 
    { 
     int yr = DateTime.Now.Year; 
     int month = DateTime.Now.Month; 

     SequenceGeneratorCollection col = new SequenceGeneratorCollection() 
      .Where(SequenceGenerator.Columns.Year, Comparison.Equals, yr) 
      .Where(SequenceGenerator.Columns.Month, Comparison.Equals, month) 
      .Load(); 

     if (col==null || col.Count == 0) 
     { 
      SequenceGenerator tr = new SequenceGenerator(); 
      tr.Year = yr; 
      tr.Month = month; 
      tr. NextNumber = 1; 
      tr.Save(); 
      return string.Format(FormatString, prefix, yr, 
         month,tr.NextNumber.ToString(NumberFormat)); 
     } 

     SequenceGenerator t = col[0]; 
     t.NextNumber += 1; 
     t.Save(); 

     return string.Format(FormatString, prefix, yr, month, 
       t.NextNumber.ToString(NumberFormat)); 
    } 
} 

Répondre

2

Ce verrou ne sera pas verrouillé si plus d'un client verrouille des objets _lock différents. Vous devez utiliser les mécanismes de verrouillage de la base de données pour cela.

+0

Le code sera accessible par l'application web. Cela fera-t-il une différence? – TheVillageIdiot

+0

Cela dépend de la façon dont votre serveur Web est configuré, il est possible de le faire engendrer plus d'un processus. Vous serez beaucoup mieux verrouillé au niveau de la base de données. –

+0

merci votre commentaire l'a scellé. – TheVillageIdiot

5

Ce verrouillage est très risqué, vous devez utiliser la transaction au niveau de la base de données si vous voulez vous assurer que les données restent cohérentes.

Le verrou (_lock) ne vous protège pas contre le fait que deux domaines d'application dialoguent avec la base de données en même temps.

+0

Le code sera accessible par une application Web. Cela fera-t-il une différence? – TheVillageIdiot

1

Non recommandé. Cela devrait être fait dans la base de données avec les champs de numéro automatique. Aussi, même si vous ne le faites pas dans DB et choisissez toujours de poursuivre de cette façon, assurez-vous que vous verrouillez le moins de code possible, n'emballez pas la méthode entière dans le verrou.