File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes EJB and other Java EE Technologies and the fly likes Container managed transaction (CMT) doesn't commit transactions Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of JavaScript Promises Essentials this week in the JavaScript forum!
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "Container managed transaction (CMT) doesn Watch "Container managed transaction (CMT) doesn New topic
Author

Container managed transaction (CMT) doesn't commit transactions

Leon Fleysher
Greenhorn

Joined: Nov 08, 2009
Posts: 4
Hello to the respected community.

I'm working with Jboss 4.2.3 GA and Hibernate 3.3.1 GA.
The Relevant Hibernate configuration file section is like this:
<session-factory name="java:hibernate/SessionFactory">

<!-- properties -->
<property name="connection.datasource">java:toluna_mssql_jdbc</property>
<property name="dialect">com.toluna.common.hibernate.SqlServerDialect</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property><!-- org.hibernate.transaction.CMTTransactionFactory -->
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>
<property name="hibernate.transaction.flush_before_completion">true</property>
<property name="hibernate.transaction.auto_close_session">true</property>
<property name="hibernate.connection.release_mode">after_transaction</property>
<property name="hibernate.connection.defaultNChar">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_minimal_puts">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.max_fetch_depth">1</property>
<property name="hibernate.jdbc.batch_size">250</property>
<property name="current_session_context_class">thread</property>
...
What happens is that under heavy load all threads are stuck waiting for db (MSSQL 2008). All transactions are waiting for a specific one that isn't committed. SQL profiler shows that this transaction has 400+ SQL commands since last commit. This transaction is not committed and it holds locks that prevent other transactions from continuing. This transaction has all locks granted and doesn't wait for other locks.

Our usage of Hibernate session is like this:
SessionFactory sf = configuration.buildSessionFactory();
Session s = new sf.getCurrentSession();
// do work with s

We don't have neither commit nor session close since we rely on CMT to do it for us.

My question is:
How can it be that transaction isn't committed by Hibernate or by Jboss and 400+ SQL commands are waiting for commit that never comes?

P.S. I have message-driven beans and they are annotated as @ejb.transaction type="Required"


Víctor Sánchez Hórreo
Greenhorn

Joined: Dec 01, 2009
Posts: 5
Hi Leon.

I am developing an application that has a very similar scenario and I have found exactly the same problem that you describe when the application works under heavy load.

Have you found any answer for this problem?

Thanks in advance.

Rregards.
Leonardo Carreira
Ranch Hand

Joined: Apr 07, 2009
Posts: 489

Hi..

do you use EJB3?..
i think you could Inject Hibernate Session inside EJB if you're working with EJB3..

please correct me if i'm wrong..
Thanks..


Sorry, perhaps my english language isn't too good.. Prepare for SCJP 6, Please God help me.. ☼
References : [Java.Boot] [JavaChamp] [JavaPrepare]
Víctor Sánchez Hórreo
Greenhorn

Joined: Dec 01, 2009
Posts: 5
Hi Leonardo.

In my case I am using EJB3 (concretely MDBs) and the access to Hibernate session is that way:

org.hibernate.Session hibernateSession = (org.hibernate.Session) manager.getDelegate();

, where manager is the EntityManager declared with the @PersistenceContext annotation:

@PersistenceContext
private EntityManager manager;

Anything wrong with this?

Thanks.
Leonardo Carreira
Ranch Hand

Joined: Apr 07, 2009
Posts: 489

You could inject it directly as follows :

@PersistenceContext
private Session session;

and then, have you tried use JTA?..
i always use JTA to handle transaction in CMT..
Víctor Sánchez Hórreo
Greenhorn

Joined: Dec 01, 2009
Posts: 5
I have supposed that JTA was used by JBoss when managing transactions, isn't it?

The MDBs I am using handle transactions in CMT mode, so I don't use explicit begins or commits using UserTransaction objects or similar.

I think the problem that causes an indefinitely lock in database tables is that there is a transaction that is neither commited nor rolled back, but I don't know how this situation can happen. If a system exception would be launched and not caught I think the roll-back would be automatic and in the case of application transactions, if all of them are properly caughted, the MDB onMessage method execution should finish and a commit should be done.

Any ideas about the origin of the problem?

Thanks.
Leon Fleysher
Greenhorn

Joined: Nov 08, 2009
Posts: 4
Víctor Sánchez Hórreo wrote:Hi Leon.

I am developing an application that has a very similar scenario and I have found exactly the same problem that you describe when the application works under heavy load.

Have you found any answer for this problem?

Thanks in advance.

Rregards.


Well Victor, the issue is resolved after a merge with another branch so I have no exact clue to solution but at least one serious issue was fixed during the merge:
I had s.createQuery but no execution command for that query where s is a regular hibernate session. I suspect that this can cause the trouble described in my original post when executed enough times.
Can you look in your code for all createQuery and ensure that there are execute commands after all of them? And let us know if this solved your problem. May be hibernate community already has a mention of this problem?
Leonardo Carreira
Ranch Hand

Joined: Apr 07, 2009
Posts: 489

Víctor Sánchez Hórreo wrote:
The MDBs I am using handle transactions in CMT mode, so I don't use explicit begins or commits using UserTransaction objects or similar.


As far as i know that if we use JTA in CMT we've to use explicit commits/rollback..
the begin transaction is described in a TransactionAttributeType, in your case the TransactionAttributeType is required...
Leon Fleysher
Greenhorn

Joined: Nov 08, 2009
Posts: 4
Leonardo Carreira wrote:
Víctor Sánchez Hórreo wrote:
The MDBs I am using handle transactions in CMT mode, so I don't use explicit begins or commits using UserTransaction objects or similar.


As far as i know that if we use JTA in CMT we've to use explicit commits/rollback..
the begin transaction is described in a TransactionAttributeType, in your case the TransactionAttributeType is required...


All I wanted to say is that if you use explicit call to s.createQuery then you must also call explicitly to s.uniqueResult() or to s.list() or something else. If you forget and s.createQuery is called many times it may lead eventually to the events I described in my main post.
Víctor Sánchez Hórreo
Greenhorn

Joined: Dec 01, 2009
Posts: 5
Thanks Leon.

I have reviewed all the createNamedQuery calls in the code and all are followed by a getSingleResult or getResultList method, so it is possible that that is not the point. Anyway I appreciate very much your advice.

I will continue researching...
Leonardo Carreira
Ranch Hand

Joined: Apr 07, 2009
Posts: 489

Ok thanks guys..
Nice discussion..
Víctor Sánchez Hórreo
Greenhorn

Joined: Dec 01, 2009
Posts: 5
I have been debugging the app and I think the problem could be related to these messages that appear in the jboss.log:

ERROR [org.jboss.resource.adapter.jms.inflow.JmsServerSession] org.jboss.resource.adapter.jms.inflow.JmsServerSession@1ecb654 failed to commit/rollback
javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can't commit because the transaction is in aborted state
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1418)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)
at org.jboss.resource.adapter.jms.inflow.JmsServerSession$XATransactionDemarcationStrategy.end(JmsServerSession.java:494)
at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:248)
at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:756)
at java.lang.Thread.run(Thread.java:619)

Could it be that an error causes the transaction to be aborted so the MDB can't commit it and the transactions remains open?
What kind of error could it be in this case?

Thanks.
Leon Fleysher
Greenhorn

Joined: Nov 08, 2009
Posts: 4
Víctor Sánchez Hórreo wrote:I have been debugging the app and I think the problem could be related to these messages that appear in the jboss.log:

ERROR [org.jboss.resource.adapter.jms.inflow.JmsServerSession] org.jboss.resource.adapter.jms.inflow.JmsServerSession@1ecb654 failed to commit/rollback
javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can't commit because the transaction is in aborted state
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1418)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)
at org.jboss.resource.adapter.jms.inflow.JmsServerSession$XATransactionDemarcationStrategy.end(JmsServerSession.java:494)
at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:248)
at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:756)
at java.lang.Thread.run(Thread.java:619)

Could it be that an error causes the transaction to be aborted so the MDB can't commit it and the transactions remains open?
What kind of error could it be in this case?

Thanks.


If you use explicit transaction demarcation it's a common practice to enclose transaction in try.. catch..finally and close the connection in finally clause. In this case even after exception the connection will be closed.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Container managed transaction (CMT) doesn't commit transactions