NHibernate with Autofac in ASP.NET (MVC): ITransaction

What is the best approach for managing NHibernate transaction using Autofac in a web application?

My session approach

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

In ITransaction , I found an example in Google Code, but it relies on HttpContext.Current.Error when deciding on a rollback.

Is there a better solution? And how much transaction volume should NHibernate have?

+6
asp.net-mvc nhibernate autofac transactions
source share
3 answers

I posted this a while ago:

http://groups.google.com/group/autofac/browse_thread/thread/f10badba5fe0d546/e64f2e757df94e61?lnk=gst&q=transaction#e64f2e757df94e61

Changed so that the interceptor has the ability to log, and the [Transaction] attribute can also be used in the class.

 [global::System.AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] public class TransactionAttribute : Attribute { } public class ServicesInterceptor : Castle.Core.Interceptor.IInterceptor { private readonly ISession db; private ITransaction transaction = null; public ServicesInterceptor(ISession db) { this.db = db; } public void Intercept(IInvocation invocation) { ILog log = LogManager.GetLogger(string.Format("{0}.{1}", invocation.Method.DeclaringType.FullName, invocation.Method.Name)); bool isTransactional = IsTransactional(invocation.Method); bool iAmTheFirst = false; if (transaction == null && isTransactional) { transaction = db.BeginTransaction(); iAmTheFirst = true; } try { invocation.Proceed(); if (iAmTheFirst) { iAmTheFirst = false; transaction.Commit(); transaction = null; } } catch (Exception ex) { if (iAmTheFirst) { iAmTheFirst = false; transaction.Rollback(); db.Clear(); transaction = null; } log.Error(ex); throw ex; } } private bool IsTransactional(MethodInfo mi) { var atrClass = mi.DeclaringType.GetCustomAttributes(false); foreach (var a in atrClass) if (a is TransactionAttribute) return true; var atrMethod = mi.GetCustomAttributes(false); foreach (var a in atrMethod) if (a is TransactionAttribute) return true; return false; } } 
+4
source share

When I use autofac, I use the same method with the container, but instead of passing the same session to my / DAO repository objects, I pass UnitOfWork, which is the container. This unit of work has this in the constructor.

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

And utility:

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

I (ab) use autofac's deterministic material for deletion to handle this, and I kind of love it.

Another thing is that I am mainly focused only on ASPNet and made an informed decision that the transaction is tied to a web request. Therefore, the transaction to the web request template.

Because of this, I can do this error handling code in the IHttpModule module:

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

I didn't look too closely at NHibernate.Burrow, but I'm sure there is something out there that does most of this.

+4
source share

I usually manage the transaction myself.

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

All Articles