These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: connection pool not closing connections correctly?
PostPosted: Mon Aug 18, 2008 11:46 am 
Newbie

Joined: Thu Jul 31, 2008 4:17 pm
Posts: 5
So I'm having a couple problems that seem to be related.

Basic idea of the app
I'm developing a desktop application with MS Visual Studio .NET 2005. At the moment, I'm persisting a single class in a single table with no inheritance or relations to other objects. It's pretty straightforward.

I have 2 "feed" objects that, once a second (based on a timer), query for the newest row. I have another object that is dumping rows into the table once a second. For every query or insert, I open a brand new session and then close it. See code snippet below.

The problems
Over some period of time (seems to vary), I stop getting updates, but no exceptions are thrown. So I'm guessing the threads are just blocking. I've verified that the GUI continues to work just fine, so it seems the entire app hasn't crashed.

Also, when I open up MySQL Administrator and view server connections, I notice that at the start, I have just 3 connections. The time for each never gets above 1-2. Over time however, one of those connections will go to sleep and never wake up. The other 2 keep chugging along with the same times. Then one of them goes to sleep... and a new connection pops up. I let this go awhile and ended up with close to 10 connections, with all but 2-3 sleeping. While the connection count was going up, the app did seem to be working still.


So the question is, why are threads going to sleep indefinitely? Why is the pool not disposing of these connections?


Hibernate version:
1.2.1

Name and version of the database you are using:
MySQL 5.0.51a
mysql-connector-net-5.2.2

Notes
NavigationEntity is the persisted object. Again it's a simple object with some various fields.

Any mutex object is of this form:
Object mutex = new Object();


This is the relevant code from the "feed" object
Code:
private bool GetLatestNav(out NavigationEntity navEnt)
{
        bool success = false;
        navEnt = null;
           
        // Get the hibernate session and start a new transaction
        ISession sess = NhibernateHelper.Instance().GetNewSession();
        ITransaction tx = sess.BeginTransaction();

        // Build the query and limit to 1 result (the newest)
        IQuery q = sess.CreateQuery("from NavigationEntity navEnt where navEnt.TailNumber=\"" + this.tailNumber + "\" order by navEnt.Received desc");
        q.SetMaxResults(1);

        // Run the query
        IList<NavigationEntity> resultSet = q.List<NavigationEntity>();

        if (resultSet.Count > 0) // be sure the query returned a result
        {
                // save the result
                navEnt = (NavigationEntity)resultSet[0];
                success = true;
        }
        else
        {
                Trace.WriteLine("Database query returned no navigation entites");
        }

        // Clean up
        tx.Commit();
        sess.Close();
        sess.Dispose();
       

        // all done
        return success;
}


Relevant Code for the table populator
Code:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
        lock (this.mutex)
        {               
                // Calculate next positions
                this.primaryNavData = CalculateNextPosition();
                this.secondaryNavData = CalculateNextPosition();

                // Put the data into the database
                ISession sess = NhibernateHelper.Instance().GetNewSession();
                ITransaction tx = sess.BeginTransaction();

                sess.Save(this.primaryNavData);
                sess.Save(this.secondaryNavData);

                //Cleanup
                tx.Commit();
                sess.Close();
                sess.Dispose();
        }
}


NhibernateHelper GetNewSession Code
Code:
public ISession GetNewSession()
{
        return this.sessionFactory.OpenSession();
}


Hibernate Config File
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <!-- an ISessionFactory instance -->
  <session-factory>
    <!-- properties -->
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
    <property name="connection.release_mode">on_close</property>
    <property name="connection.connection_string">
      Database=rgs;Data Source=localhost;User Id=root;Password=
    </property>
    <property name="dialect">NHibernate.Dialect.MySQLDialect</property>
    <property name="show_sql">true</property>
    <!-- mapping files -->
    <mapping assembly="DataAccessManager" />
  </session-factory>
</hibernate-configuration>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 18, 2008 12:34 pm 
Newbie

Joined: Thu Jul 31, 2008 4:17 pm
Posts: 5
Update:

I let the software run for like 15minutes and it finally threw an exception. At the time of exception, the database showed 14 connections!!

The exception
Code:
NHibernate.ADOException was unhandled by user code
  Message="cannot open connection"
  Source="NHibernate"
  StackTrace:
       at NHibernate.Impl.SessionFactoryImpl.OpenConnection()
       at NHibernate.Impl.ConnectionManager.GetConnection()
       at NHibernate.Impl.SessionImpl.get_Connection()
       at NHibernate.Transaction.AdoTransaction.Begin(IsolationLevel isolationLevel)
       at NHibernate.Transaction.AdoTransaction.Begin()
       at NHibernate.Impl.ConnectionManager.BeginTransaction()
       at NHibernate.Impl.SessionImpl.BeginTransaction()
       at DataAccessManager.Navigation.NavigationFeed.GetLatestNav(NavigationEntity& navEnt) in \DataAccessManager\Navigation\NavigationFeed.cs:line 216
       at DataAccessManager.Navigation.NavigationFeed.OnTimedEvent(Object source, ElapsedEventArgs e) in \DataAccessManager\Navigation\NavigationFeed.cs:line 187
       at System.Timers.Timer.MyTimerCallback(Object state)


The inner exception
Code:
System.NullReferenceException
{"Object reference not set to an instance of an object."}

Source
"MySql.Data"

Stack Trace
at MySql.Data.MySqlClient.MySqlPool.CheckoutConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open()
at NHibernate.Connection.DriverConnectionProvider.GetConnection()
at NHibernate.Impl.SessionFactoryImpl.OpenConnection()


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 18, 2008 3:17 pm 
Newbie

Joined: Thu Jul 31, 2008 4:17 pm
Posts: 5
I upgraded to the newest MySQL Connector for .NET (5.2.3) and it seems to have corrected the problem. It ran for a little over a half hour without leaving any dormant connections.

Possibly related to this bug


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 27, 2008 1:42 pm 
Newbie

Joined: Thu Jul 31, 2008 4:17 pm
Posts: 5
The unexplained behavior is BACK. The application is opening a new connection with every single query I make, and the connection doesn't appear to ever be closed. It just sleeps.

The querying code:
Code:
private Object hibernateMutex = new Object();

public IList<CollectionEntry> GetUpdated(DateTime time)
{
        ISession sess = null;
        ITransaction tx = null;
        ICriteria criteria = null;
        IList<CollectionEntry> resultSet = null;

        lock (this.hibernateMutex)
        {
                // Get the hibernate session and start a new transaction
                sess = NhibernateHelper.Instance().GetNewSession();
                tx = sess.BeginTransaction();

                // Build the query
                criteria = sess.CreateCriteria(typeof(CollectionEntry))
                    .Add(Expression.Gt("LastModified", time));

                // Run the query
                resultSet = criteria.List<CollectionEntry>();

                // Make sure there are reults
                if (resultSet.Count <= 0)
                    return null;    // return null if no results

                // Cleanup
                tx.Commit();
                sess.Close();
                sess.Dispose();
        }

        return resultSet;
}


Upgraded to NHibernate 2.0.0 GA
Tried MySQL Connector/NET 5.1.7 and 5.2.3

If it's relevant, the persisted class, CollectionEntry, has only one member that is an object of another class, which is mapped as a many-to-one and is polymorphic (only 1 subclass at this time). I can produce the mappings, if relevant.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.