hibernate version: Hibernate 2.1.2
database: PostgreSQL 7.4.3 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.3.3 (Debian 20040422)
I (think) I am having problems with transactions staying open. I want to verify that it is a problem. The symptom is that I start up my program (which runs in a servlet container) and there is always (at least) one "idle in transaction" process per SessionFactory. This may be acceptable, but I want to find out. I have questions throughout the code...
Here is a snippet from the
test program I have written:
Code:
// just the classes I want to use
Class[] classes = {
StandardResource.class,
Author.class,
Group.class,
User.class,
PhysicalLocation.class,
Contribution.class
};
// load some boring properties file - see properties file later on in the message
Properties config = new Properties();
FileInputStream fis = new FileInputStream( new File( "../build/properties/resource-hibernate.properties") );
config.load( fis );
Class.forName( "org.postgresql.Driver" );
Configuration cfg = new Configuration();
cfg.setProperties( config );
for( int i = 0; i < classes.length; i++ )
{
cfg.addClass( classes[i] );
}
SessionFactory fact = cfg.buildSessionFactory();
log.debug("sessoin factory created");
// I have these sleeps in here so I can check the running processes and capture the logs...
Thread.sleep(10000);
when I look at the database logs I see this
Code:
LOG: connection received: host=192.168.1.3 port=4129
LOG: connection authorized: user=postgres database=mydb
LOG: statement: set datestyle to 'ISO'; select version(), case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else
getdatabaseencoding() end;
LOG: statement: set client_encoding = 'UNICODE'
LOG: statement: begin;
notice the "begin;" statement - this is starting a transaction. This means that just by creating a SessionFactory I have a transaction created. Is this correct or just some weird PostgreSQL thing?
continuing with the code
Code:
Session session = fact.openSession();
Transaction tx = session.beginTransaction();
log.debug( "autocomit is : " + session.connection().getAutoCommit() ); // returns "false"
log.debug("transaction started");
Thread.sleep(10000);
tx.commit();
log.debug("commit");
The tx.commit() causes the previous transaction to be finished, but immediately opens a new transaction
Code:
LOG: statement: commit;begin;
Code:
Thread.sleep(2000);
session.close();
log.debug("close");
Thread.sleep(2000);
log.debug("done");
Thread.sleep(10000);
if I do a "ps aux | grep postgres" I can still see that there is a postgres transaction that is "idle in transaction"
Code:
log.debug( "is the session still connected? : " + session.isConnected() );
fact.close();
Again, if I do a "ps aux | grep postgres" the "idle in transaction" message has gone, BUT there has been no command executed on the database. This means that the "begin;" that was executed earlier didn't have a corresponding "commit;" added to it, but (I assume) the socket connection to the db is closed. Is this ok?
Code:
// again, just so I can stuff around at the OS level and see what is happening.
Thread.sleep( 10000 );
my properties file that I load in
Code:
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.generated.forced = true
hibernate.show_sql = false
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://192.168.1.253/mydb
hibernate.connection.username = postgres
hibernate.connection.password = NONE_OF_YOUR_BUSINESS
database.jar = C:/programming/java/persistence/postgres/pg
74.213.jdbc3.jar
database.name = mydb
Any feedback on what is going on, to help my understanding of the issues, would be appreciated.
Mark