[jboss-dev] Oops, javax.naming.spi.* is dependent on Hashtable, this will make it difficult to change the JBoss jndi naming service to use ConcurrentHashMap instead of Hashtable...

Scott Marlow scott.marlow.opensource at gmail.com
Wed Jul 11 16:15:32 EDT 2007


Scott Marlow wrote:
> Adrian wrote:
>> On Wed, 2007-07-11 at 11:58 -0400, Scott Marlow wrote:
>>   
>>> Hi Adrian,
>>>
>>> The 2-3 second contention that I'm seeing is on the following call stack:
>>>
>>> "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
>>> ..."
>>>
>>>
>>> I am looking at changing the Hashtable to a ConcurrentHashMap which 
>>> could help some applications run more concurrently. 
>>>     
>>
>> This just looks like a bug in Hibernate. 
>>
>> It is caching the naming context in the JTATransactionFactory
>> and then using it concurrently across threads, without 
>> the required synchronization.
>>
>> This probably only works by luck, because it is looking up in
>> "java:comp" for the UserTransaction which is a read only context
>> constructed at deployment time and is therefore unlikely 
>> to have concurrency problems.
>>
>> I'm sure if this class was changed to create a new initial context
>> for each request you wouldn't see the contention, but that
>> might not be very efficient either. Depends how often the
>> isTransactionInProgress() is invoked.
>>
>> I don't see why it isn't caching the UserTransaction instead anyway.
>> It's probably because some people use Hibernate across transaction
>> demarcation boundaries in at least dubious, if not broken ways. 
> Hibernate does offer a few alternatives to the JTATransactionFactory 
> (applications can also implement their own 
> org.hibernate.transaction.TransactionFactory solution).  There is a 
> JDBC based implementation that shouldn't have this problem. There is 
> also a CMT solution that also shouldn't hit this problem (it caches a 
> transactionmanager.) 
>
> I'll try caching the UserTransaction in the Hibernate 
> JTATransactionFactory. 
>
I tried caching the UserTransaction and that eliminated the contention. 

I owe you a pint the next time you visit! 

Thanks,
Scott



More information about the jboss-development mailing list