2009-06-24 3 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

Код будет доступен через веб-приложение. Будет ли это иметь значение? – TheVillageIdiot

+0

Это зависит от того, как настроен ваш веб-сервер, возможно, он породил несколько процессов. Вам будет намного лучше блокироваться на уровне базы данных. –

+0

благодарит ваш комментарий, запечатал его. – TheVillageIdiot

5

Этот замок действительно рискованно, вы должны использовать транзакции на уровне базы данных, если вы хотите, чтобы гарантировать, что данные остаются когерентными.

Блокировка (_lock) не защищает вас от одновременного использования двух доменов приложений одновременно с БД.

+0

Код будет доступен через веб-приложение. Будет ли это иметь значение? – TheVillageIdiot

1

Не рекомендуется. Это должно быть сделано в БД с автоматическими номерами полей. Кроме того, даже если вы не делаете этого в БД и по-прежнему предпочитаете преследовать этот путь, убедитесь, что вы заблокировали наименьшее количество кода, не оберните весь метод блокировкой.

Смежные вопросы