Использование нескольких слушателей NHibernate, которые делают обновления базы данных? - PullRequest
1 голос
/ 06 декабря 2011

Я использую NHibernate 2.1 и у меня есть некоторые слушатели, которые реализуют IPreInsertEventListener, IPreUpdateEventListener, IPreDeleteEventListener.

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

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

Вот пример того, что делают два разных слушателя:

// Generic audit listener (audits everything)
public bool OnPreUpdate(PreUpdateEvent evnt)
{
    // Ignore audit entries, otherwise we go round and round
    if (!(evnt.Entity == AuditEntry))
    {
        ISession session = evnt.Session.GetSession(EntityMode.Poco);
        // create AuditEntry for the updated Entity
        // ...
        session.Save(auditEntity);
        session.Flush();
    }
}

// Restricted audit listener (only interested in a handful of entities)
public bool OnPreUpdate(PreUpdateEvent evnt)
{
    if (evnt.Entity is RelevantToThisListener) // etc
    {
        ISession session = evnt.Session.GetSession(EntityMode.Poco);
        // create or modify some other audit entity
        // ...
        session.Save(auditEntity);
        session.Flush();
    }
}

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

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

Спасибо

1 Ответ

1 голос
/ 07 декабря 2011

Вариант 1: var isolatedSession = evnt.Session.Factory.OpenSession();

Вариант 2: удалить session.Flush(); из слушателей

Я бы предпочел Вариант 2, потому что

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