【问题标题】:NHibernate Session gets disposed off on each wcf service method callNHibernate Session 在每个 wcf 服务方法调用上被释放
【发布时间】:2010-07-07 08:50:58
【问题描述】:

我在 Sharp Architecture 中使用 Wcf。我已经使用 WcfSessionStorage 等按照北风示例配置了我的项目。我在 wcf 服务中有一个方法,它使用 Repository.GetAll() 获取业务对象列表。我正在使用 WcfTestClient 测试服务方法。第一次调用该方法时,一切正常。但是在随后的调用中,我在 Repository.GetAll() 方法上得到以下异常

[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'

似乎 NHibernate 会话在每次调用后都会被释放。我通过使用以下属性装饰我的服务解决了这个问题

[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}

但是这意味着,每次调用都会创建一个服务实例,这反过来又会创建一个新的休眠会话等。在我的场景中,每次调用都不需要创建一个新的服务实例,我认为这很昂贵过程而不是正确的解决方案。我想知道我的场景中的最佳实践是什么,以及如何通过每次调用创建一个新的服务实例来让这个东西发挥作用。

谢谢 纳比尔

【问题讨论】:

    标签: wcf nhibernate s#arp-architecture


    【解决方案1】:

    最简单的方法是每次都创建一个新实例,这不是一个昂贵的过程,因为在 .NET 中创建一个新对象就像 0.00000000000000001 秒(我在 Ayande 的博客或其他地方读到过)。

    我在我的项目中使用 Autofac DI,我通常将 ISession 作为容器范围(每个请求一个)。然后每个使用(直接或间接) ISession 的类都必须是容器范围或更低(工厂范围 == 每个类使用都是一个新实例)。如果使用 ISession 的类的范围更大(会话范围 == 单例),您将遇到当前遇到的问题。

    如果您的服务是单例服务: 首次运行时会创建服务,该服务使用 ISession,它应该是容器范围的,并且在第一次运行时。 对服务的下一个请求(现在已创建服务)仍然引用已创建的 ISession(已在上一个结束请求中关闭),所以现在它已关闭。

    我不推荐使用与您打开/关闭相同的 ISession(在 NHibernate 文档中不推荐),只使用容器范围(我这样做并且我没有任何性能问题),或者您应该在服务中的每个方法中手动创建 ISession,例如:

    using(ISession s = ISessionFactory.OpenSession())
         using(ITransaction t = .....)
    ....
    

    但这一点都不好......

    【讨论】:

      【解决方案2】:

      请看看我对我自己的类似问题的回答:WCF/S#arpArch: underlying ISession is closed after the first call within a request

      @dmonlord 是对的,在这种情况下,在同一个请求中创建额外的会话实例非常便宜。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-01
        • 1970-01-01
        • 2015-11-29
        • 2021-07-02
        • 2010-09-06
        • 1970-01-01
        相关资源
        最近更新 更多