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 populatorCode:
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 CodeCode:
public ISession GetNewSession()
{
return this.sessionFactory.OpenSession();
}
Hibernate Config FileCode:
<?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>