Мы внедрили систему аудита через прослушиватели событий NHibernate. В нашем слушателе мы отслеживаем все изменения и записываем их в наши таблицы аудита. Чтобы попытаться максимизировать производительность, мы использовали Guid для наших таблиц аудита, чтобы мы могли как можно больше пакетировать наши обновления.
Мы записываем обновления для «дочернего сеанса», которые мы получаем следующим образом:
protected ISession GetSession(AbstractEvent @event)
{
if (@event == null)
{
throw new ArgumentNullException("event");
}
ISession childSession = @event.Session.GetSession(EntityMode.Poco);
return childSession;
}
Из документации NHibernate этот сеанс должен быть "дочерним" сеансом, который наследует все атрибуты своего родителя, включая транзакцию.
Как только мы создали объект, мы сохраняем его в сеансе с:
childSession.Save(auditLogEntry);
Все это вызывается внутри транзакции, и я ожидаю, что изменения, сделанные в childSession, сбрасываются после фиксации транзакции. К сожалению, ничего не происходит и изменения не сбрасываются.
Следует отметить, что я могу заставить это работать с ручным сбросом сразу после сохранения, но это не будет работать для нас, потому что изменения больше не будут пакетироваться (что приведет к неприемлемой производительности).
Сначала я думал, что это поведение ограничено событиями, но я смог абстрагировать его в модульный тест для дублирования поведения.
public void When_Saving_Audit_Log_Records_To_Child_Session_Flushes_When_Transaction_Committed()
{
ISession session = GetSession();
session.FlushMode = FlushMode.Commit;
ITransaction transaction = session.BeginTransaction();
ISession childSession = session.GetSession(EntityMode.Poco);
AuditLogEntry entry = CreateAuditLogEntry();
entry.AddAuditLogEntryDetail(CreateAuditLogEntryDetail());
entry.AddAuditLogEntryDetail(CreateAuditLogEntryDetail());
childSession.Save(entry);
transaction.Commit();
}
protected ISession GetSession()
{
return _sessionFactory.OpenSession();
}
Я знаю, что это не ваш обычный вопрос о NHibernate, но если у кого-то есть какой-либо опыт или совет, которым я могу поделиться, я бы с удовольствием его услышал.
У меня есть 2 секунды до того, как я просто записываю записи аудита в очередь, но я хотел исчерпать все возможности, прежде чем сдаться.
Заранее спасибо,
Steve