【发布时间】:2013-12-19 00:25:21
【问题描述】:
因此,基于我上周提出的这个问题 (here),我决定去看看 Castle 项目并使用 Castle.Facilities.NHibernateIntegration 设施。
我花了两天时间弄乱它并遇到了同样的问题:NHibernate Thread-Safe Sessions。我希望开箱即用的内置 ISessionManager 足够智能以处理线程,这就是我决定实现它的原因。
在关于该特定项目的非常稀疏的文档中,它提到调用 ISessionManager.OpenSession 与调用 session.GetCurrentSession 大致相同。据此,我认为我无法强制打开一个新的单独会话。
那么有没有人为我提供解决方案或任何想法我可以如何解决这个问题?
(我知道大多数人会说只使用一个线程,但老实说,跳出框框思考,一些工具和例程会自动生成一个新线程。例如,log4net 和 sessionstatestore。你不能只是假设会有只有一个线程,关联,与当前请求。)
注意事项:
我正在使用 .NET 4 Web 应用程序开发 Web 模型。
我以通常的记录方式调用和解析 Windsor 容器,并让容器解析会话管理器。我在两个线程中都这样做。
这是我的 Castle NHibernate 配置:
代码:
<facility id="nhibernate" isWeb="true" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
<factory id="nhibernate.factory">
<settings>
<item key="connection.connection_string">#{NHibernateConnectionString}</item>
<item key="connection.driver_class">#{NHibernateDriver}</item>
<item key="connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
<item key="dialect">#{NHibernateDialect}</item>
<item key="generate_statistics">true</item>
<item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
<item key="show_sql">true</item>
</settings>
<assemblies>
<assembly>Gigastence.Base.Common</assembly>
</assemblies>
</factory>
- 这是我的 DAO 示例
代码:
public class NHibernateDao : INHibernateDao
{
private ISessionManager sessionManager;
public NHibernateDao(ISessionManager sessionManager)
{
this.sessionManager = sessionManager;
}
public void Append(LoggingEvent loggingEvent)
{
using (IStatelessSession session = sessionManager.OpenStatelessSession())
{
using (ITransaction tran = session.BeginTransaction())
{
Log data = new Log
{
Id = Guid.NewGuid(),
Date = loggingEvent.TimeStamp,
Level = loggingEvent.Level.ToString(),
Logger = loggingEvent.LoggerName,
Thread = loggingEvent.ThreadName,
Message = loggingEvent.MessageObject.ToString()
};
if (loggingEvent.ExceptionObject != null)
{
data.Exception = loggingEvent.ExceptionObject.ToString();
}
session.Insert(data);
tran.Commit();
}
}
}
}
- 以及我如何称呼 DAO。 注意:这是在我无法控制的新产生的线程上。
代码:
public class NHibenateAppender : AppenderSkeleton
{
protected override void Append(LoggingEvent loggingEvent)
{
if(IoC.IsInitialized)
{
var NHibernateLogger = IoC.Resolve<INHibernateDao>();
NHibernateLogger.Append(loggingEvent);
}
}
}
【问题讨论】:
标签: multithreading nhibernate thread-safety castle-windsor castle