Недостатки динамического обновления NHibernate?

Есть ли причина не использовать dynamic-insert/dynamic-update для NHibernate? Единственная причина, по которой я спрашиваю, - это то, что я хотел бы включить как по умолчанию, а не как что-то, что мне нужно было бы настроить.

Есть ли какие-либо ошибки, которые следует учитывать при использовании этих динамических свойств?

Ответы

Ответ 1

Для некоторых объектов вы можете создать недопустимое состояние, но динамические обновления. Скажем, у вас есть Class с Boolean Свойством A и логически зависимым Integer Свойством B. Если свойство A равно True, то свойство B может быть только отрицательным числом, а если свойство A равно False, то свойство B может быть только положительным числом.

Скажем, что два пользователя взаимодействуют с экземпляром этого класса за определенный промежуток времени. Для начала пользователи Alice и Bob материализуют этот класс из базы данных с начальными значениями A= True и B= -50

Database   Alice       Bob
A: True    A: True     A: True
B: -50     B: -50      B: -50
VALID      VALID       VALID

Пользователь Alice изменяет A на False и B на 125 и передает его в базу данных. Теперь мы имеем следующую ситуацию:

Database   Alice       Bob
A: False   A: False    A: True
B: 125     B: 125      B: -50
VALID      VALID       VALID

Пользователь Bob не меняет A, но меняет B на -75, а затем записывает его в базу данных. Если динамические обновления включены, NHibernate видит, что Боб только изменил B на -75 и выдает динамическое обновление, которое редактирует только значение B. Если у вас была проверка SQL на сервере, чтобы предотвратить B от отрицания, если только A не было true, вы получили бы ошибку SQL здесь, но позвольте сказать, что вы не воспроизвели всю свою бизнес-логику в своих таблицах SQL. Вот результирующие данные:

Database   Alice       Bob
A: False   A: False    A: True
B: -75     B: 125      B: -75
INVALID    VALID       VALID

И у Алисы, и у Боба есть действительные состояния, но База данных теперь находится в недопустимом состоянии! Пользователь Чарли приходит и пытается материализовать эту запись:

Database   Alice       Bob       Charlie
A: False   A: False    A: True   A: False
B: -75     B: 125      B: -75    B: -75 
INVALID    VALID       VALID     INVALID

Charlie скорее всего получит ошибку проверки из вашего приложения, когда NHibernate попытается установить свойство B нового экземпляра вашего класса.

Итак, когда у вас есть логически зависимые свойства, у вас должна быть стратегия для избежания этой ситуации. Одна из возможностей - просто включить select-before-update для этого объекта. Это может привести к некоторым дополнительным вызовам в базе данных и немного более низкой производительности. Другим является использование версий в NHibernate, что означало бы, что, когда Боб пытается сохранить свою запись, запрос на вставку NHibernate не будет запускать какие-либо записи и выкидывать исключение устаревшей информации (которое может быть изящно обработано). Вы также можете кодифицировать логические требования своего класса в базе данных, однако тогда вам следует быть осторожными, чтобы убедиться, что база данных и программа имеют одинаковые кодифицированные требования с течением времени, и у вас будет несколько мест для вносить изменения при изменении требований, что не всегда стоит накладных расходов.

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

Ответ 2

Динамическая вставка и обновление имеют небольшую стоимость, потому что NHibernate должен каждый раз строить SQL, а не кэшировать его. Я не знаю, есть ли стоимость на стороне базы данных. Динамическая вставка и обновление очень удобны для устранения неполадок и профилирования. Если бы я смог измерить значимый удар производительности, я бы включил его в разработку и отключение в процессе производства.

Вы можете столкнуться с проблемами с прослушивателями и перехватчиками, см. этот вопрос.

Я включил его в приложениях NHibernate без проблем. Мой ответ - нет, нет веской причины не использовать его.