2013-05-03 2 views
5

Мне нужно заручиться несколькими сеансами NHibernate за одну транзакцию. В настоящее время я делаю следующее:Несколько сеансов NHibernate в одном Transanction

1) Создайте SQL-соединение, dbConn;

2) Позвоните по номеру ISession session = ISessionFactory.OpenSession (dbConn) для создания первой сессии;

3) Позвоните по номеру session.BeginTransaction(), чтобы начать транзакцию.

4) Позже в коде, я создаю новую сессию с той же связи:

ISession сессии2 = ISessionFactory.OpenSession (DBConn)

При попытке запустить любой запрос к session2, появляется следующее сообщение об ошибке:

ExecuteReader требует, чтобы команда имела транзакцию, когда соединение, назначенное команде, находится в ожидающем локальном t ransaction. Свойство Transaction команды не инициализировано.

NHibernate, похоже, не привлекает второе ISession (или, более конкретно, объект Command, которое он создает для этого сеанса) в открытой транзакции, даже если он повторно использует одно и то же соединение.

Есть ли способ иметь несколько сеансов в рамках одной и той же транзакции?

Я не могу использовать один сеанс, потому что у меня многолетняя задача, которая загружает и создает более 1 миллиона объектов. Если я использую один ISession, производительность снижается с 3000 запросов к базе данных в секунду до 20 из-за ухудшения производительности NHibernate Flushes. Чтобы решить эту проблему, я хотел бы создать недолгосрочные сессии и быстро распоряжаться ими.

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

ответ

7

вещи, которые вы можете сделать

  • session.GetSession() создавать дочерние сеансы с тем же контекстом (соединение, транзакция, режим)
  • , если вам не нужно использовать каскадные StatelessSession, который предназначен для этого
  • используйте session.Clear(); после каждых 50 предметов или около того
+0

* У ISession, похоже, нет CreateSession, по крайней мере, от 3.3.1. Этот метод находится в другом месте или находится в новой версии NHibernate? * Я уже обнаружил ISession.Clear(), и он отлично поработал. Это хорошее предложение. – Alex

+1

жаль, что это должно быть 'ISession.GetSession (EntityMode.Poco)'. починил это – Firo

Смежные вопросы