Autofac,NHibernate ISession和MVC每个请求的事务。正确使用Session和Transaction的是什么样的?

时间:2014-03-02 23:10:14

标签: c# asp.net-mvc nhibernate transactions

我正在使用AutoFac在MVC中实现Transaction-per-Request模式。我有以下内容:

public static void RegisterDaoFactory()
{
    var containerBuilder = new ContainerBuilder();

    containerBuilder.RegisterControllers(Assembly.GetAssembly(typeof(Streamus)));
    containerBuilder.Register(x => NHibernateSessionManager.Instance.SessionFactory).SingleInstance();
    containerBuilder.Register(x => x.Resolve<ISessionFactory>().OpenSession()).InstancePerHttpRequest();
    containerBuilder.Register(x => LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType)).As<ILog>().InstancePerHttpRequest();

    IContainer container = containerBuilder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

public abstract class StreamusController : Controller
{
    protected readonly ILog Logger;
    protected new readonly ISession Session;
    private ITransaction Transaction;

    protected StreamusController(ILog logger, ISession session)
    {
        if (logger == null) throw new ArgumentNullException("logger");
        if (session == null) throw new ArgumentNullException("session");

        Logger = logger;
        Session = session;
    }

    protected override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        base.OnActionExecuting(actionContext);

        Transaction = Session.BeginTransaction();
    }

    protected override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);

        try
        {
            if (Transaction.IsActive)
            {
                if (actionExecutedContext.Exception != null)
                    Transaction.Rollback();
                else
                    Transaction.Commit();
            }
        }
        finally
        {
            Transaction.Dispose();
        }
    }

    protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonNetResult
        {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            JsonRequestBehavior = behavior
        };
    }

}

Autofac为我打开并关闭了ISession,就像冠军一样。我很确定我需要自己处理交易。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我会在控件操作中直接调用BeginTransaction(),在需要的地方和时间。您通常希望事务的生命周期更短。此外,通过这种方式,您可以选择不在不需要的情况下打开事务,例如重定向。

此外,请不要忘记使用

using(var transaction = Session.BeginTransaction())
{
    // Database code here
}
,以便您的交易始终处置,例外或不处理。