NHibernate с Autofac в ASP.NET (MVC): ITransaction
-
06-07-2019 - |
Вопрос
Каков наилучший подход к управлению транзакциями 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){
...
}
}