0

I'm using ninject to manage my session for a Web API/MVC application. The code is as follows:

Bind<ISession>().ToMethod(c => c.Kernel.Get<ISessionFactory>().OpenSession())
            .InRequestScope()
            .OnActivation(s => s.BeginTransaction())
            .OnDeactivation((s) =>
            {
                try
                {
                    s.Transaction.Commit();
                }
                catch (Exception e)
                {
                    s.Transaction.Rollback();
                }

                s.Close();
                s.Dispose();
            });
    }

The OnActivation code is called correctly - when the session is injected a transaction is begun. However when the request finishes, the ondeactivation is not called. Therefore I can query things from the database but not commit changes (unless I commit the transaction elsewhere).

I'm not really sure why the OnDeactivation isn't being called - am I missing something in my ninject setup?

Bonnotbh
  • 515
  • 7
  • 24

1 Answers1

0

Calling Commit during OnDeactivation is a really bad idea, because OnDeactivation will always be called, even if an exception is thrown from within the business layer. In case of an error, you clearly don't want to commit the transaction.

You should consider committing on a different level. This q/a talks about this in more detail and shows how to solve this problem.

Also note that your code is overly verbose. If you call Dispose, you don't have to call Close and if you call Dispose on an uncommitted transaction, the transaction is automatically rolled back. You can even pull the plug, the database will automatically rollback an uncommitted transaction. In other words, you can easily simplify your code to the following:

.OnDeactivation((s) =>
{
    try
    {
        s.Transaction.Commit();
    }
    finally
    {
        s.Dispose();
    }
});

You can even remove the Dispose when you make use of the OnePerRequestHttpModule as described here. This reduces the code further to:

.OnDeactivation(s => s.Transaction.Commit());

But again, OnDeactivation is absolutely the wrong place to commit.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • noted - will move the commit elsewhere. my issue was that ondeactivation wasn't being called (ever) though - any idea why that might be? – Bonnotbh Aug 04 '16 at 16:04
  • 1
    @Bonnotbh OnDeactivation and disposal is usually undeterministic in Ninject. Ninject will clean up after garbage is collected by th GC. This is often not workable for database connections. – Steven Aug 04 '16 at 16:10