2009-06-24 11 views
0

Ich habe eine Tabelle, die Sequenznummer enthält.Ist diese Verriegelung in Ordnung?

Tabellenstruktur

SequenceGenerator 
    Year int 
    Month int 
    NextNumber int 

Jahr + Monat machen Primärschlüssel. Die Sequenz wird jeden Monat zurückgesetzt.

Ich benutze Subsonic, um DAL zu generieren. nächste Sequenznummer zu bekommen ich eine Klasse geschrieben haben, die nächste Nummer Anforderer zurückgibt:

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)); 
    } 
} 

Antwort

2

Diese Sperre wird nicht aktiviert, wenn mehr als ein Client verschiedene _lock-Objekte sperrt. Sie sollten dafür die Datenbanksperrmechanismen verwenden.

+0

Der Code wird von der Webanwendung aufgerufen. Wird es einen Unterschied machen? – TheVillageIdiot

+0

Es hängt davon ab, wie Ihr Webserver konfiguriert ist. Es ist möglich, dass mehr als ein Prozess generiert wird. Sie werden viel besser auf Datenbankebene sperren. –

+0

danke dein Kommentar versiegelt es. – TheVillageIdiot

5

Diese Verriegelung wirklich riskant ist, sollten Sie Datenbank-Level-Transaktion verwenden, wenn Sie kohärentes sicherstellen wollen, bleiben die Daten.

Die Sperre (_lock) schützt Sie nicht davor, dass zwei App-Domänen gleichzeitig mit der DB kommunizieren.

+0

Der Code wird von der Webanwendung aufgerufen. Wird es einen Unterschied machen? – TheVillageIdiot

1

Nicht empfohlen. Dies sollte in DB mit Auto-Nummernfeldern geschehen. Auch wenn Sie dies nicht in der DB tun und trotzdem diesen Weg einschlagen, vergewissern Sie sich, dass Sie für die kleinste Menge an Code sperren, nicht die ganze Methode in die Sperre einschließen.

Verwandte Themen