我正在使用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年前了。
非常感谢您的帮助。