NHibernate: выберите значение MAX одновременно - PullRequest
0 голосов
/ 04 декабря 2009

Предположим, мне нужно выбрать максимальное значение в качестве номера заказа. Таким образом, я выберу MAX (число), назначу номер для заказа и сохраню изменения в базе данных. Тем не менее, как я могу предотвратить, чтобы другие возились с номером? Будут ли транзакции делать? Что-то вроде:

     ordersRepository.StartTransaction();
     order.Number = ordersRepository.GetMaxNumber() + 1;
     ordersRepository.Commit();

Изменится ли приведенный выше код «блокировки», чтобы номера заказов читались / записывались только одним клиентом БД? Учитывая, что транзакции являются обычными транзакциями NHibernate, а GetMaxNumber просто выполняет SELECT MAX (Number) FROM Orders.

1 Ответ

1 голос
/ 05 декабря 2009

Использование ITransaction с IsolationLevel.Serializable должно сделать эту работу. Однако будьте осторожны в борьбе за стол. Если у вас есть высокочастотные обновления на столе, вещи могут сильно замедлиться. Возможно, вы захотите профилировать попадание в БД при использовании GetMaxNumber().

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

Использование отдельной таблицы Counter имеет пару плюсов:

  • Устраняет конфликт в таблице Order
  • Обычно быстрее
  • Если он достаточно мал, его можно закрепить в памяти

Я также использовал сохраненный процесс для возврата следующего доступного идентификатора:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
  UPDATE [COUNTER] SET Value = Value + 1 WHERE COUNTER_ID = @counterId
COMMIT TRAN

RETURN [NEW_VALUE]

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...