C# NHibernate会话/事务在IIS6和Visual Studio 2008调试服务器上的行为不同
我正在使用HttpModule来处理我的NHibernate会话和事务。我有很多页面都对没有在IIS6框上成功启动的事务非常恼火,但当我在本地运行它们时,尤其是当我在回发期间尝试调用事务的Commit()以使用新更新的数据刷新数据网格时,这些页面就不会这样。在本地调试代码时不会发生这些错误 本地和服务器的web.config文件相同 服务器上是否有一些配置可能会导致与我的本地VS Debug服务器处理的IIS上的模块的行为差异 模块代码如下所示:C# NHibernate会话/事务在IIS6和Visual Studio 2008调试服务器上的行为不同,c#,visual-studio-2008,nhibernate,iis-6,C#,Visual Studio 2008,Nhibernate,Iis 6,我正在使用HttpModule来处理我的NHibernate会话和事务。我有很多页面都对没有在IIS6框上成功启动的事务非常恼火,但当我在本地运行它们时,尤其是当我在回发期间尝试调用事务的Commit()以使用新更新的数据刷新数据网格时,这些页面就不会这样。在本地调试代码时不会发生这些错误 本地和服务器的web.config文件相同 服务器上是否有一些配置可能会导致与我的本地VS Debug服务器处理的IIS上的模块的行为差异 模块代码如下所示: public class NHibernateS
public class NHibernateSessionModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += BeginTransaction;
context.EndRequest += CommitAndCloseSession;
}
private static void BeginTransaction(object sender, EventArgs e)
{
if (HttpContext.Current.Request.RawUrl.Contains(".aspx"))
{
NHibernateSessionManager.Instance.InitSessionFactory();
NHibernateSessionManager.Instance.BeginTransaction();
}
}
private static void CommitAndCloseSession(object sender, EventArgs e)
{
if (HttpContext.Current.Request.RawUrl.Contains(".aspx"))
{
try
{
NHibernateSessionManager.Instance.FlushSession();
NHibernateSessionManager.Instance.CommitTransaction();
}
finally
{
NHibernateSessionManager.Instance.CloseSession();
}
}
}
public void Dispose() { }
}
相关经理代码如下:
private void InitSessionFactory()
{
if (sessionFactory != null)
{
return;
}
var cfg = new Configuration();
// The following makes sure the the web.config contains a declaration for the HBM_ASSEMBLY appSetting
if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["HBM_ASSEMBLY"]))
{
throw new ConfigurationErrorsException(
"NHibernateManager.InitSessionFactory: \"HBM_ASSEMBLY\" must be " +
"provided as an appSetting within your config file. \"HBM_ASSEMBLY\" informs NHibernate which assembly " +
"contains the HBM files. It is assumed that the HBM files are embedded resources. An example config " +
"declaration is <add key=\"HBM_ASSEMBLY\" value=\"MyProject.Core\" />");
}
// Don't make session factories for foundations that share a database
string hibernateString = BaseAccess.GetHibernateConnectionString();
cfg.AddAssembly(ConfigurationManager.AppSettings["HBM_ASSEMBLY"]);
cfg.SetProperty("connection.connection_string", hibernateString);
sessionFactory = cfg.BuildSessionFactory();
}
public void BeginTransaction()
{
if (threadTransaction == null ||
threadTransaction.WasCommitted ||
threadTransaction.WasRolledBack ||
!threadTransaction.IsActive)
{
threadTransaction = GetSession().BeginTransaction();
}
}
public ISession GetSession()
{
if (null == sessionFactory)
{
InitSessionFactory();
}
if ((threadSession == null || !threadSession.IsOpen) && null != sessionFactory)
{
threadSession = sessionFactory.OpenSession();
}
return threadSession;
}
private void FlushSession()
{
if (null != threadSession && threadSession.IsOpen)
{
threadSession.Flush();
}
}
public void CommitTransaction()
{
try
{
if (threadTransaction!= null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive)
{
threadTransaction.Commit();
threadTransaction = null
}
}
catch (HibernateException)
{
RollbackTransaction();
throw;
}
}
public void RollbackTransaction()
{
try
{
if (threadTransaction != null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive)
{
threadTransaction.Rollback();
}
}
finally
{
CloseSession();
}
}
private void CloseSession()
{
if (threadSession != null && threadSession.IsOpen)
{
threadSession.Close();
}
}
private void InitSessionFactory()
{
if(sessionFactory!=null)
{
返回;
}
var cfg=新配置();
//以下内容确保web.config包含HBM_程序集appSetting的声明
if(string.IsNullOrEmpty(ConfigurationManager.AppSettings[“HBM_ASSEMBLY”]))
{
抛出新的ConfigurationErrorsException(
“NHibernateManager.InitSessionFactory:\“HBM\U程序集\”必须是”+
“作为配置文件中的应用设置提供。\“HBM\U程序集\”通知NHibernate哪个程序集”+
“包含HBM文件。假定HBM文件是嵌入式资源。示例配置”+
“声明是”);
}
//不要为共享数据库的基金会创建会话工厂
字符串hibernateString=BaseAccess.GetHibernateConnectionString();
cfg.AddAssembly(ConfigurationManager.AppSettings[“HBM_ASSEMBLY”]);
SetProperty(“connection.connection_string”,hibernateString);
sessionFactory=cfg.BuildSessionFactory();
}
公共无效开始生效()
{
if(threadTransaction==null||
threadTransaction.WasCommitted||
threadTransaction.WasRolledBack||
!threadTransaction.IsActive)
{
threadTransaction=GetSession().BeginTransaction();
}
}
公共会话GetSession()
{
if(null==会话工厂)
{
InitSessionFactory();
}
if((threadSession==null | |!threadSession.IsOpen)&&null!=sessionFactory)
{
threadSession=sessionFactory.OpenSession();
}
返回会话;
}
私有void FlushSession()
{
if(null!=threadSession&&threadSession.IsOpen)
{
threadSession.Flush();
}
}
公共无效委托交易()
{
尝试
{
if(threadTransaction!=null&&!threadTransaction.WasCommitted&&!threadTransaction.WasRolledBack&&threadTransaction.IsActive)
{
提交();
threadTransaction=null
}
}
捕获(休眠异常)
{
回滚事务();
投掷;
}
}
公共无效回滚事务()
{
尝试
{
if(threadTransaction!=null&&!threadTransaction.WasCommitted&&!threadTransaction.WasRolledBack&&threadTransaction.IsActive)
{
threadTransaction.Rollback();
}
}
最后
{
CloseSession();
}
}
私有会话()
{
if(threadSession!=null&&threadSession.IsOpen)
{
threadSession.Close();
}
}
猜测,因为未包含完整的代码:
您将会话存储在线程中,线程的行为是否不同?您应该将会话存储在httpcontext中,它可能会很好。通常是“事务未成功启动”我将会话和线程移动到HttpContext.Current.Items中,并且发生了完全相同的行为。移动到HttpContext和手动关闭并处理连接的组合似乎解决了此问题。我添加了一个块,用于在出现“Not Started”错误时启动事务,并且它似乎也捕获了需要在该上下文中发生的任何操作,因此现在一切都很好。