2009-06-24 6 views
0

私はシーケンス番号を含むテーブルを持っています。これはロックされていますか?

表構造

SequenceGenerator 
    Year int 
    Month int 
    NextNumber int 

年+月には、主キーを作ります。シーケンスは毎月リセットされます。

私はSubsonicを使用してDALを生成しています。私は、リクエスタに次の番号を返すクラスを書いた次のシーケンス番号を取得するには:

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

答えて

2

複数のクライアントが異なる_lockオブジェクトをロックしている場合、このロックは使用できません。これにはデータベースロックメカニズムを使用する必要があります。

+0

コードはWebアプリケーションからアクセスされます。何か違いはありますか? – TheVillageIdiot

+0

Webサーバーの設定によって、複数のプロセスを起動させることができます。あなたは、データベースレベルでロッキングする方がずっと良いでしょう。 –

+0

コメントしていただきありがとうございます。 – TheVillageIdiot

5

このロックを使用すると、データがコヒーレント残るようにしたい場合は、データベース・レベルのトランザクションを使用する必要があり、本当に危険です。

ロック(_lock)は、同時に2つのアプリドメインがDBと通信するのを防ぎません。

+0

コードはWebアプリケーションからアクセスされます。何か違いはありますか? – TheVillageIdiot

1

推奨しません。これは、自動番号フィールドを持つDBで行う必要があります。また、DBでこれをしていなくても、この方法を追求することを選択したとしても、コード全体をロックしないようにしてください。

関連する問題