Pregunta

¿Cuál es el mejor enfoque para administrar las transacciones de NHibernate usando Autofac dentro de la aplicación web?

Mi enfoque para la sesión es

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

Para ITransaction , tengo encontró un ejemplo en Google Code, pero se basa en HttpContext.Current.Error al decidir si retroceder.

¿Hay una mejor solución? ¿Y qué alcance debe tener la transacción de NHibernate ?

¿Fue útil?

Solución

Otros consejos

Cuando uso autofac, utilizo el mismo método de ámbito de contenedor, pero en lugar de pasar la misma sesión a mis objetos Repository / DAO, paso un UnitOfWork que es ámbito de contenedor. La Unidad de trabajo tiene esto en el constructor.

    private readonly ISession _session;
    private ITransaction _transaction;

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

Y la disposición es:

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

    }

Estoy (ab) usando el material de eliminación determinista en autofac para gestionar esto, y bueno, me gusta.

La otra cosa es que básicamente solo estoy apuntando a un entorno ASPNet y tomé una decisión consciente de que una transacción está vinculada a una solicitud web. Entonces, una transacción por patrón de solicitud web.

Por eso puedo hacer este código de manejo de errores en un IHttpModule:

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

No he echado un vistazo a NHibernate.Burrow demasiado de cerca, pero estoy seguro de que hay algo que hace la mayor parte de esto.

Generalmente administro la transacción yo mismo ..

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