I have 4 window services. All have same issue that the underlying Tcp connections to the database are not getting closed even if the Session is closed properly. I check the Session usage through NHibernateMemory Profiler.
4 Sessions were opened and 4 Sessions were closed.
Then I go and check the netstat and I see the count of Tcp connections to the database is increasing and not being released.
We have to restart our Production server twice a week due to this issue till we find a solution to this issue.
My NHibernate Config file is as below.
Code:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle9Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">Data Source=u1xmt1;User Id=scf_p_login;Password=abc123x;</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">web</property>
<property name="generate_statistics">true</property>
<mapping assembly="WellsFargo.Scf.Repository.Nh"/>
</session-factory>
</hibernate-configuration>
My NHibernate Session Code is as below:
Code:
using System;
using System.Web;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Context;
namespace WellsFargo.Scf.Platform.Dal.Nh
{
public class SessionHelper
{
private static string NHibernateSessionKey = "NHibernateSessionKey";
private static Configuration cfg;
public static ISessionFactory SessionFactory;
static SessionHelper()
{
cfg = new Configuration();
cfg.Configure();
SessionFactory = cfg.BuildSessionFactory();
}
private static ISession GetNewSession()
{
return SessionFactory.OpenSession();
}
public static ISession GetSession()
{
ISession currentSession = null;
if (IsInWebContext() && HttpContext.Current.Session == null)
{
currentSession = GetNewSession();
CurrentSession = currentSession;
}
else
currentSession = CurrentSession;
if (currentSession == null)
{
CurrentSession = GetNewSession();
currentSession = CurrentSession;
}
if (IsInWebContext())
CurrentSessionContext.Bind(currentSession);
return currentSession;
}
public static bool StartConversation()
{
ISession session = GetNewSession();
session.BeginTransaction();
if (IsInWebContext())
CurrentSessionContext.Bind(session);
else
CurrentSession = session;
return true;
}
public static bool EndConversation()
{
return EndConversation(false);
}
public static bool EndConversation(bool doRollback)
{
ISession session;
if (IsInWebContext())
session = CurrentSessionContext.Unbind(SessionFactory);
else
session = CurrentSession;
if (session != null)
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
if(doRollback)
session.Transaction.Rollback();
else
session.Transaction.Commit();
}
}
catch (Exception ex)
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Rollback();
}
finally
{
if (IsInWebContext())
{
session.Clear();
session.Close();
}
else
{
session.Dispose();
session = null;
}
}
CurrentSession = null;
return true;
}
public static bool BeginTransaction()
{
ISession session;
if (IsInWebContext())
session = CurrentSessionContext.Unbind(SessionFactory);
else
session = CurrentSession;
if(session== null)
session = GetNewSession();
session.BeginTransaction();
if (IsInWebContext())
CurrentSessionContext.Bind(session);
else
CurrentSession = session;
return true;
}
public static bool CommitTransaction()
{
ISession session;
if (IsInWebContext())
session = CurrentSessionContext.Unbind(SessionFactory);
else
session = CurrentSession;
if (session != null)
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Commit();
}
}
catch (Exception ex)
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Rollback();
}
return true;
}
public static bool RollbackTransaction()
{
ISession session;
if (IsInWebContext())
session = CurrentSessionContext.Unbind(SessionFactory);
else
session = CurrentSession;
if (session != null)
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
}
}
catch (Exception ex)
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Rollback();
}
return true;
}
private static bool IsInWebContext()
{
return HttpContext.Current != null;
}
private static ISession CurrentSession
{
get
{
if (IsInWebContext())
return HttpContext.Current.Session[NHibernateSessionKey] as ISession;
else
{
return System.Runtime.Remoting.Messaging.CallContext.GetData(NHibernateSessionKey) as ISession;
}
}
set
{
if (IsInWebContext())
{
if (HttpContext.Current.Session != null)
HttpContext.Current.Session[NHibernateSessionKey] = value;
}
else
{
System.Runtime.Remoting.Messaging.CallContext.SetData(NHibernateSessionKey, value);
}
}
}
}
}
Netstat clearly shows that the connections are still open for the process. I have logged the connections. Please find below a sample.
2011-12-29 15:00:07,833 [5] INFO InfoLogger - ----------------------------------------114
2011-12-29 15:00:07,833 [5] INFO InfoLogger - 170.13.64.193
2011-12-29 15:00:07,833 [5] INFO InfoLogger - InterNetwork
2011-12-29 15:00:07,833 [5] INFO InfoLogger - 1304
2011-12-29 15:00:07,833 [5] INFO InfoLogger - 170.13.64.217
2011-12-29 15:00:07,833 [5] INFO InfoLogger - InterNetwork
2011-12-29 15:00:07,833 [5] INFO InfoLogger - 9001
2011-12-29 15:00:07,833 [5] INFO InfoLogger - Established
2011-12-29 15:00:07,833 [5] INFO InfoLogger - ----------------------------------------
There is no issue while I am working in Web scenario. Only when it comes to Window service we have this issue.
Please help me in solving this issue. Any help will be appreciated.