每个Web请求使用Castle.Facility.AutoTx和Castle.Facility.NHibernate的nhibernate会话在openseesion时总是创建新会话

时间:2019-01-11 08:42:44

标签: c# nhibernate castle-windsor

我正在使用Castle Windors,它是AutoTx和NHibernate设备。 正如我所期望的,每个HTTP请求,The Facility都会为整个过程保留一个数据库会话。 这是我的设备配置:

        <factory id="icost.factory" alias="nh.facility.default">
            <settings>

      <add key="log4net.Internal.Debug" value="true"/>

      <add key="hibernate.show_sql" value="false" />
      <item key="connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
                <item key="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</item>
      <item key="dialect">#{nhibernateDialect}</item>
                <item key="connection.connection_string_name">#{connectionStringName}</item>
      <item key="cache.provider_class">NHibernate.Cache.HashtableCacheProvider, NHibernate</item>          
                <item key="cache.use_second_level_cache">true</item>
                <item key="cache.use_query_cache">true</item>
                <item key="relativeExpiration">300</item>
      <item key="command_timeout">12000</item>
      <item key="adonet.batch_size">250</item>
      <item key="generate_statistics">false</item>
      <item key="max_fetch_depth">5</item>
      <item key="generate_statistics">false</item>
      <add key="connection.isolation" value="ReadUncommitted" />
      <add key="current_session_context_class">managed_web</add>
      <item key="hbm2ddl.keywords">none</item>          
      <item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
      <!-- Speed things up -->
      <item key="use_proxy_validator">false</item>
      <item key="show_sql">true</item>
            </settings>

            <assemblies>
      <assembly>Business</assembly>                 
            </assemblies>

        </factory>
    </facility>

在使用ISessionManager的代码中有2个函数获取并保存

private readonly ISessionManager _sessionManager;
public virtual T FetchFirst(ICriteria criteria)
    {
        using (ISession session = _sessionManager.OpenSession(_SessionFactoryAlias))
        {
            var list = (GetExecutableCriteria(session, criteria)
                        .SetFirstResult(0)
                        .SetMaxResults(1)
                        .List<T>());

            return (list.Count > 0  ? list[0] : default(T));
        }
    }

public virtual void Save(T entity)
    {
        using (ISession session = _sessionManager.OpenSession(_SessionFactoryAlias))
        {
            session.Save(entity);
        }
    }

这是我在代码中使用上述功能的方式:

ReportValue entity = repository.FetchFirst(criteria);            
// do some change
repository.Save(entity);

一切顺利。我检查了获取操作和保存操作的会话ID,两者相同

{9a046635-ad11-4208-86ce-8de800a4649a} //fetch
{9a046635-ad11-4208-86ce-8de800a4649a} //save

但是当我尝试在标签中强调测试和并发请求时。发生错误。会话在保存和提取上有所不同

{3c8eca53-6000-4db7-a20b-5dc437ce4aaf} //fetch
{82f4a60a-c142-4b0b-97f2-89170a8a77fa} //save

我尝试了google ISessionManager的实现代码,我发现此存储库是ISessionManager的最兼容代码 https://github.com/castleproject-deprecated/Castle.Facilities.NHibernateIntegration-READONLY/blob/master/src/Castle.Facilities.NHibernateIntegration/DefaultSessionManager.cs

public ISession OpenSession(String alias)
    {
        if (alias == null) throw new ArgumentNullException("alias");

        ITransaction transaction = ObtainCurrentTransaction();

        SessionDelegate wrapped = sessionStore.FindCompatibleSession(alias);

        ISession session;

        if (wrapped == null)
        {
            session = CreateSession(alias);

            wrapped = WrapSession(transaction != null, session);
            EnlistIfNecessary(true, transaction, wrapped);
            sessionStore.Store(alias, wrapped);
        }
        else
        {
            EnlistIfNecessary(false, transaction, wrapped);
            wrapped = WrapSession(true, wrapped.InnerSession);
        }

        return wrapped;
    }

基于实现代码,该代码将在当前会话的会话存储中找到。 因此,我尝试在调试窗口中调查SessionDelegate。 并获得“ session store.FindCompatibleSession(alias)”的结果始终为空。这意味着在代码中的某处。清晰的“会话存储”是意外的。

我正在使用.Net v4.7.2。 Facility lib和.Net版本是否不兼容。因为这个lib很老,所以6年前了。

非常感谢您的帮助。

0 个答案:

没有答案