3

私はランダムに "セッションが閉じている!"Autofac、(Fluent)nHibernate、ISession "セッションが閉じられました!"断続的に

Global.asax.cs:Autofacと流暢NHibernateは、以下の構成のエラー

builder.Register(x => new NHibernateConfigurator().GetSessionFactory()).SingleInstance(); 
builder.Register(x => x.Resolve<ISessionFactory>().OpenSession()).InstancePerHttpRequest(); 

NHibernateConfigurator.cs

public class NHibernateConfigurator 
{ 
    public Configuration Configure() 
    { 
     var configuration = new Configuration(); 
     configuration.SessionFactory() 
      .Proxy.Through<ProxyFactoryFactory>() 
      .Integrate.Using<Oracle10gDialect>(); 

     FluentConfiguration fluentConfiguration = Fluently.Configure(configuration); 
     fluentConfiguration.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>()); 

     return fluentConfiguration.BuildConfiguration(); 
    } 

    public ISessionFactory GetSessionFactory() 
    { 
     var configuration = Configure(); 
     return configuration.BuildSessionFactory(); 
    } 
} 

SomeController.cs:

private readonly IRepository repository; 

public SomeController(IRepository repository) 
{ 
this.repository = repository 
} 

[Transaction] 
public ActionResult Index() 
{ 
    var result = repository.GetUsers(); 
    return View(result); 
} 

TransactionAttribute .cs

public class TransactionAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     DependencyResolver.Current.GetService<ISession>().BeginTransaction(IsolationLevel.ReadCommitted); 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     ITransaction currentTransaction = DependencyResolver.Current.GetService<ISession>().Transaction; 

     if (currentTransaction.IsActive) 
     { 
      if (filterContext.Exception != null && filterContext.ExceptionHandled) 
      { 
       currentTransaction.Rollback(); 
      } 
     } 
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     ITransaction currentTransaction = DependencyResolver.Current.GetService<ISession>().Transaction; 

     base.OnResultExecuted(filterContext); 
     try 
     { 
      if (currentTransaction.IsActive) 
      { 
       if (filterContext.Exception != null && !filterContext.ExceptionHandled) 
       { 
        currentTransaction.Rollback(); 
       } 
       else 
       { 
        currentTransaction.Commit(); 
       } 
      } 
     } 
     finally 
     { 
      currentTransaction.Dispose(); 
     } 
    } 
} 

IRepository.cs:

public interface IRepository 
{ 
    IList<User> GetUsers();  
} 

Repository.cs:

public class Repository : IRepository 
{ 
    private readonly ISession session; 

    public Repository(ISession session) 
    { 
     this.session = session; 
    } 

    public IList<User> GetUsers() 
    { 
     return session.QueryOver<User>().List(); 
    } 
} 

この現在のセット・アップ作品が、(カッシーニのいくつかのページのリロードまたは再起動後に)断続的に失敗しているようですGetUsersが「セッションは閉じています!」とスローします。エラー。私はInstancePerHttpRequestにISessionFactoryを登録することでこれらの問題を回避できると考えました。運がない。何か案は? nHibernateとAutofacの新機能ですので、十分な関連情報を投稿できなかった場合はお知らせください。

+0

MVC 3を使用していますか?トランザクション管理はアクションフィルタで管理されますか? – Chev

+0

MVC 3、はい。トランザクション管理、はい。そのスニペットを含めるのを忘れた - それを追加しました。 – heyseuss

+0

同じ問題がありました。 MVC 3の問題であるように見えますが、情報へのリンクを見つけることはできませんが、コントローラに注入されるようにISessionを移動してください。修正されました。むしろセッションを制御する方が良いので、UIに表示する必要があるかもしれない問題が発生する前に、リクエストが閉じるまで待つ必要はありません。 – Chev

答えて

1

私の設定は任意のNHibernateはコールのために完璧に働いている表示されます私のカスタムメンバーシッププロバイダーとカスタムロールプロバイダー以外では、私が知る限り問題になります。つまり、この問題は実際に問題に対処していません。

+0

アクションフィルタを確認するためにいくつかのログを追加してください。私たちは、HEAVYトラフィックがスローされた環境でしかこれを見つけられませんでした – Chev

0

Repositoryはどのように登録されていますか?それはInstancePerHttpRequest(これはすべきですか)、またはSingleton(これではならない)ですか?

+0

"builder.RegisterType <リポジトリ()。();"としてください。 ()の後に.InstancePerHttpRequest()をアタッチしても問題は解決しませんでした。 – heyseuss

0

私はMVC 3アクションフィルタを使って同様の問題を抱えており、MVC 3でかなり積極的にキャッシュされているようで、OnActionExecutedとしてセッションが常に起動するとは限りません。あなたが取引をラップしたいあなたの行動で

public SomeController(
     ISession session, 
     ILogger logger, 
     IRepository<Something> someRepository) 
    { 
     _session = session; 
     _logger = logger; 
     _someRepository = someRepository; 
    } 

はそうのように、コントローラのコンストラクタにあなたのセッションを移動

using (var transaction = _session.BeginTransaction()) 
{ 
    // do something with your repository 
    _someRepository.Add(new Something()); 
    transaction.commit(); 
} 
関連する問題