Spring не закрывать сессию после транзакции nhibernate - PullRequest
2 голосов
/ 06 марта 2012

У меня следующий код объявления:

<tx:advice id="txAdvice" transaction-manager="TransactionManager">
    <tx:attributes>
        <tx:method name="Get"/>
        <tx:method name="Update"/>
    </tx:attributes>
</tx:advice>

Я вызываю методы "Get" и "Update" из функции "X".

Метод "Update" вызывает исключение "Другой объект"с тем же значением идентификатора уже был связан с сеансом "

Как закрыть сеанс во время Spring после выполнения метода?

Обновление информации:

Iпостараюсь более точно описать проблему.

У меня есть проект MVC.Контроллеры вызывают менеджеров (они представляют бизнес-логику).Менеджеры используют репозитории для взаимодействия с БД.При действии обновления я делаю следующее:

  • вызов метода Get менеджера для получения учетной записи
  • изменение некоторых свойств
  • вызов метода обновления менеджера дляобновление этой учетной записи.

Каждая функция менеджера заключена в транзакцию AOP.Когда я вызываю метод Update, он пишет ошибку.Похоже, это потому, что объект Account все еще привязан к сеансу, который был открыт для функции Get.Я пытался открыть и закрыть сессию непосредственно в функции Get (без AOP).В этом случае все работает правильно.

Итак, вопрос в том, почему объект Account все еще прикрепляется к сеансу после вызова Get?

Имхо, вы не используете интерфейсы для вашего репо, а Spring не может создать декоратор AOP.

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

1 Ответ

2 голосов
/ 07 марта 2012

Из комментариев к вашему вопросу я понимаю, что ваши прокси AOP настроены правильно.Я понимаю, что у вас есть класс менеджера, подобный этому:

public class Manager : ISomeInterfaceToProxy
{
  object Get(...) {}
  void Update(object toUpdate) {}
}

Этот класс менеджера рекомендуется использовать с перехватчиком транзакций из вашего вопроса.Этот менеджер вводится в ваш контроллер, который сначала вызывает Get() (инициация и завершение первой транзакции), а затем Update(...).Важно понимать, что вызов Update(...) инициирует вторую транзакцию , что может привести к ошибке, о которой вы упоминаете, когда область действия сеанса не "на запрос".Если сеанс не найден, каждая транзакция создаст новый сеанс.

Существует несколько решений:

  1. Убедитесь, что сеанс остается открытым в течение всего веб-запроса, например, используйте openсеанс в представлении, как в spring.net сеанс / транзакция nhibernate на запрос
  2. Вызов подпрограмм Get(...) и Update(...) из другого метода, который заключен в рекомендацию по транзакции, так чтотранзакция распространяется между вызовами методов
...