Пусть NHibernate извлекает определенные свойства при каждом вызове - PullRequest
0 голосов
/ 29 октября 2010

Обычно, когда вы определяете отображение для определенного свойства класса, NHibernate сохраняет значение в свойстве, как только оно было выбрано. Либо он извлекается сразу при получении объекта, либо лениво загружается при первом вызове метода получения свойства, но как только он был загружен из базы данных, он извлекается.

Пожалуйста, поправьте меня, если я ошибаюсь.

Можно ли настроить отображение таким образом, чтобы каждый отдельный вызов одного и того же геттера заставлял NHibernate перейти в базу данных и снова прочитать значение?

Справочная информация: у меня есть таблица и соответствующий класс ExcelFile, который управляет путями и метаданными некоторых файлов Excel. Каждый ExcelFile объект представляет один файл.

ExcelFile содержит свойства IsLocked, LockedBy и DateLocked, чтобы заблокировать файл, пока кто-то над ним работает. Как только он закрывает файл, блокировка снимается.

Кэширование этих свойств может привести к условиям гонки:

  • Алиса загружает запись в БД для ее отображения. Также отображается IsLocked. Это ложь. NHibernate кэширует значение.
  • Боб делает то же самое, это ложь.
  • 5 минут спустя Алиса открывает файл: приложение снова проверяет IsLocked и затем устанавливает блокировку.
  • Боб открывает файл: приложение проверяет IsLocked, которое было кэшировано и все еще false. Поэтому он устанавливает блокировку и открывает приложение.

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

Однако мне нужно запросить записи с IsLocked, установленным с использованием HQL. Также собственное кодирование методов, которые просто читают и записывают соответствующее поле таблицы, вводит второе место, где сопротивляется логике отображения, что не очень приятно.

1 Ответ

1 голос
/ 04 ноября 2010

Вы, вероятно, можете сделать это, я слышал, что nHibernate теперь поддерживает отложенную загрузку свойств, что является шагом в этом направлении.

Но, сказав это, у вас все равно будет состояние гонки.Один из способов избежать состояния гонки - это следующее:

  1. начать транзакцию
  2. получить объект с помощью get или refresh (используйте блокировку обновления, это позволит избежать блокировок при бобе иАлиса нажала на БД в одно и то же время)
  3. Проверить, является ли IsLocked верным, если это так, прервать
  4. Установить IsLocked = true
  5. Подтвердить транзакцию.
...