Калитка, аутентификация и разграничение транзакций - PullRequest
1 голос
/ 16 июня 2011

Я использую Wicket с пользовательским PageAuthorizationStrategy, который обращается к базе данных для получения информации о текущем пользователе и, следовательно, его правах доступа.Каждый запрос оборачивается фильтром Spring Open-Session-In-View, чтобы открыть / закрыть сеанс Hibernate.

Это прекрасно работает для чтения доступа к базе данных.Когда бы ни происходили операции записи, я вызываю сервисный уровень, который использует обработку транзакций Spring на основе аннотаций.Это также работает, но я думаю, что это является причиной определенной ошибки: когда объект загружается во время аутентификации в запросе A, затем модифицируется в другом запросе B и затем передается на уровень обслуживания в запросе A, уровень обслуживания работает сневерные значения, поскольку ни Hibernate, ни базовая база данных не могут обеспечить изоляцию.Поскольку я всегда немного борюсь со спецификой теории баз данных / транзакций, пожалуйста, исправьте меня, если это предположение уже неверно.

Моей первой идеей решения было обновить объекты, загруженные для аутентификации сразу после записи.сделка была начата.Однако это вызывает проблемы, когда объект, который должен быть изменен службой, одновременно необходим для аутентификации.Это особенно происходит, когда Wicket заполняет объект измененными данными из формы, и он передается службе в методе отправки (например).

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

Как бы я поступил так по «правильному пути» в Wicket?

РЕДАКТИРОВАТЬ: Эта проблема стала еще более серьезной, так как я понял, что когда метод службы с транзакциями выполняет откат после создания исключения, слой представления вызывает исключение LazyInitializationException.Очевидно, что Spring TransactionManager очищает сеанс и / или что-то еще в недрах Hibernate / Spring не работает, так как я могу перезагрузить объект из базы данных, но попытка загрузить коллекцию, содержащуюся в этом объекте, вызывает указанное исключение.Есть идеи, как это сделать?Я полагаю, что все это было бы решено, если бы существовал элегантный способ использовать «одну транзакцию на запрос».

Ответы [ 2 ]

1 голос
/ 18 июня 2011

Это не проблема Wicket, а проблема DB / Hibernate.Hibernate имеет поддержку как для оптимистических, так и для пессимистических стратегий.

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

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

Обаесть плюсы и минусы, и оба требуют, чтобы вы активно использовали функции и код, чтобы заставить его работать (без волшебной пыли).

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

Пессимисту придется иметь дело с проблемами конкуренции и масштабируемости.

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

Пессимисту придетсявсегда беспокоиться о блокировке при работе с обновлениями этой таблицы (вы забыли заблокировать в одном месте, и вы просто heisenbug ).

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

1 голос
/ 16 июня 2011

Я не уверен, что это даже вопрос о "правильном пути" в Wicket, я бы попытался решить это в слое service / dao, есть некоторые возможности, такие как:

  • не используйте шаблон OSIV для информации, которая необходима в «реальном времени», OSIV сияет, когда используется в таблицах для отображения информации об элементе без необходимости запрашивать базу данных
  • прикреплять отредактированные / измененные атрибуты к объекту, напримеротметка времени последнего изменения, перед любой операцией записи вы можете проверить отметки времени и предупредить / компенсировать изменения из «будущего» * ​​1006 *
...