[hibernate-dev] Caching result (UserTransaction) of jndi lookup in o.h.t.JTATransactionFactory
Scott Marlow
scott.marlow.opensource at gmail.com
Thu Jul 12 10:43:45 EDT 2007
Hi,
I was seeing excessive object lock contention in the JBoss jndi naming
service due to the following call sequence repeating in my application:
"PooledInvokerThread-192.169.1.2: java.util.Hashtable.get :335
> PooledInvokerThread-192.169.1.2: org.jnp.interfaces.NamingContext.useAbsoluteName :1090
> PooledInvokerThread-192.169.1.2: org.jnp.interfaces.NamingContext.getObjectInstance :1123
> PooledInvokerThread-192.169.1.2: org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure :1142
> PooledInvokerThread-192.169.1.2: org.jnp.interfaces.NamingContext.lookup :705
> PooledInvokerThread-192.169.1.2: org.jnp.interfaces.NamingContext.lookup :587
> PooledInvokerThread-192.169.1.2: javax.naming.InitialContext.lookup :351
> PooledInvokerThread-192.169.1.2: org.hibernate.transaction.JTATransactionFactory.isTransactionInProgress :83
> PooledInvokerThread-192.169.1.2: org.hibernate.jdbc.JDBCContext.isTransactionInProgress :180
> PooledInvokerThread-192.169.1.2: org.hibernate.jdbc.JDBCContext.registerSynchronizationIfPossib :158
> PooledInvokerThread-192.169.1.2: org.hibernate.impl.SessionImpl.checkTransactionSynchStatus :1850
> PooledInvokerThread-192.169.1.2: org.hibernate.impl.SessionImpl.getEntityMode :1274
> PooledInvokerThread-192.169.1.2: org.hibernate.engine.StatefulPersistenceContext.addEntry :415
> PooledInvokerThread-192.169.1.2: org.hibernate.engine.StatefulPersistenceContext.addEntity :382
> PooledInvokerThread-192.169.1.2: org.hibernate.engine.TwoPhaseLoad.addUninitializedEntity :240
> PooledInvokerThread-192.169.1.2: org.hibernate.loader.Loader.loadFromResultSet :1358
> PooledInvokerThread-192.169.1.2: org.hibernate.loader.Loader.instanceNotYetLoaded :1300
> PooledInvokerThread-192.169.1.2: org.hibernate.loader.Loader.getRow :1197
> ..."
My first thought was to improve the AS class org.jnp.interfaces.NamingContext to use a ConcurrentHashMap instead of Hashtable for the JNDI namespace. However, the Sun naming classes are dependent on Hashtable being used. I could copy the ConcurrentHashMap to a new Hashtable when needed but I didn't want to cause even more memory copying to occur in the JNDI name space handling (there is already way too much cloning going on). I started to attempt building a hybrid Hashtable class that is backed by a ConcurrentHashMap but then I received some excellent feedback on the AS dev forum. Adrian suggested caching the UserTransaction object in o.h.t.JTATransactionFactory, although he said that might not work for some applications.
I tried this and it work great for me. Are there any cases where doing the "ut = ( UserTransaction ) context.lookup( utName )" at the time that method "configure(Properties props)" is invoked, would return a different value than later when "isTransactionInProgress()" is invoked?
I think that getting the UserTransaction early is a good performance enhancement for JTATransactionFactory.
Any disagreement?
I'll Jira this and fix if we agree with the change.
Scott
More information about the hibernate-dev
mailing list