Ayende @ Rahien

It's a girl

What is the cost of opening a session?

Damien Guard asked me an interesting question:

Is SessionFactory.OpenSession() very lightweight because you call it on every request even if you have pages that don't need it.
I would have thought the lazy construction in CurrentSession get would have been a little safer.

The answer is that it is literally not worth your time to write the lazy construction. Here is what is happening when you opening a session:

public ISession OpenSession(IDbConnection connection, bool flushBeforeCompletionEnabled, bool autoCloseSessionEnabled,
							ConnectionReleaseMode connectionReleaseMode)
{
	return
		new SessionImpl(connection, this, true, settings.CacheProvider.NextTimestamp(), interceptor,
						settings.DefaultEntityMode, flushBeforeCompletionEnabled, autoCloseSessionEnabled,
						connectionReleaseMode);
}

We new up a SessionImpl, which in turn:

internal SessionImpl(
	IDbConnection connection,
	SessionFactoryImpl factory,
	bool autoclose,
	long timestamp,
	IInterceptor interceptor,
	EntityMode entityMode,
	bool flushBeforeCompletionEnabled,
	bool autoCloseSessionEnabled,
	ConnectionReleaseMode connectionReleaseMode)
	: base(factory)
{
	using (new SessionIdLoggingContext(SessionId))
	{
		if (interceptor == null)
			throw new AssertionFailure("The interceptor can not be null.");

		rootSession = null;
		this.timestamp = timestamp;
		this.entityMode = entityMode;
		this.interceptor = interceptor;
		listeners = factory.EventListeners;
		actionQueue = new ActionQueue(this);
		persistenceContext = new StatefulPersistenceContext(this);
		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
		this.connectionReleaseMode = connectionReleaseMode;
		connectionManager = new ConnectionManager(this, connection, connectionReleaseMode, interceptor);

		if (factory.Statistics.IsStatisticsEnabled)
		{
			factory.StatisticsImplementor.OpenSession();
		}

		if (log.IsDebugEnabled)
		{
			log.Debug(string.Format("[session-id={0}] opened session at timestamp:{1}", SessionId, timestamp));
		}

		CheckAndUpdateSessionStatus();
	}
}

Is going to setup its fields and new up some additional stuff as well. All the work that is being done is merely newing up a few objects, and that is lightning fast. There is no database involved, NHibernate will manage the database connection to ensure minimal time spent with an open database connection automatically.

Comments

Jan Willem B
08/16/2009 05:47 AM by
Jan Willem B

For me the reason to do lazy session initialization is to get a cleaner view in nhprof. If there are a lot of requests (images etc), nhprof can be quite cluttered with empty sessions.

Ayende Rahien
08/16/2009 05:49 AM by
Ayende Rahien

Jan,

NH Prof is going to have an option to ignore empty sessions soon

Comments have been closed on this topic.