Вопрос

Каков наилучший подход к управлению транзакциями NHibernate с использованием Autofac в веб-приложении?

Мой подход к сессии -

builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
       .ContainerScoped();

Для ITransaction у меня есть нашел пример в коде Google, но при решении вопроса об откате он опирается на HttpContext.Current.Error .

Есть ли лучшее решение? И какую область действия должна иметь транзакция NHibernate ?

Это было полезно?

Решение

Я недавно это опубликовал:

Другие советы

Когда я использую autofac, я использую тот же метод области контейнера, но вместо того, чтобы передавать тот же сеанс моим объектам Repository / DAO, я передаю UnitOfWork, который является областью контейнера. Единица работы имеет это в конструкторе.

    private readonly ISession _session;
    private ITransaction _transaction;

    public UnitOfWork(ISession session)
    {
        _session = session;
        _transaction = session.BeginTransaction();
    }

И распоряжение это:

    public void Dispose()
    {
        try
        {
            if (_transaction != null &&
                            !_transaction.WasCommitted &&
                            !_transaction.WasRolledBack)
                _transaction.Commit();
            _transaction = null;
        }
        catch (Exception)
        {
            Rollback();
            throw;
        }

    }

Я (ab) использую детерминистские утилиты для удаления в autofac, чтобы справиться с этим, и мне это нравится.

Другое дело, что я в основном ориентируюсь только на среду ASPNet и принял сознательное решение о том, что транзакция связана с веб-запросом. Таким образом, транзакция по шаблону веб-запроса.

Из-за этого я могу сделать этот код обработки ошибок в модуле IHttpModule:

    void context_Error(object sender, System.EventArgs e)
    {
        _containerProvider.RequestContainer.Resolve<IUnitOfWork>().Rollback();
    }

Я не слишком внимательно смотрел на NHibernate.Burrow, но уверен, что есть кое-что, что делает большую часть этого.

Обычно я управляю транзакцией самостоятельно.

public ActionResult Edit(Question q){
try {
 using (var t = repo.BeginTransaction()){
  repo.Save(q);
  t.Commit();
  return View();
 }
 catch (Exception e){
  ...
 }
}
scroll top