Atomikos Forum

Cannot perform commit when using executeQuery in transaction

Hi!

I ´ve been testing the new version of Atomikos with the new AtomikosDataSourceBean. Here is the config:

<Resource name="jdbc/datasource"
            auth="Container" type="com.atomikos.jdbc.AtomikosDataSourceBean"            factory="com.atomikos.tomcat.BeanFactory"        uniqueResourceName="jdbc/datasource"    xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource"
maxPoolSize="3"            xaProperties.URL="jdbc:oracle:thin:@..:1521:.."
            xaProperties.user="..."
            xaProperties.password=".."/>

When I use with source code that worked in the 3.2.0 release like this:

UserTransaction ut=null;

DAO1 dao1=new DAO1();
DAO2 dao2=new DAO2();
DAO3 dao3=new DAO3();

boolean commit=false;

try{

  ut=getTransaction();
  ut.begin();

  Object obj1=dao1.getSomeObjectFromDB(Integer id);
 
  dao2.updateThings(obj1);

  dao3.deleteThings(obj1);
 
  ut.commit();
 
  if(!commit){
    ut.rollback();
  }

}finally{

}

Inside every DAO I´ve always the same structure:

public class DAO1 {

public void getSomeObjectFromDB() throws Exception{

  Connection con=null;
  try{
    con=getConnection();
    con.executeQuery..
  }finally{
  if (con!=null) con.close();
  }
 }
}

public class DAO2 {

public void updateThings(Object obj) throws Exception{

  Connection con=null;
  try{
    con=getConnection();
    con.executeUpdate..
  }finally{
  if (con!=null) con.close();
  }
 }
}

When I execute the source code below the DAO, I´ve a exception: "Cannot perform commit".

I checked that it works perfectly if I move out the transaction begin-commit scope the DAO objects that only execute query operations, not updating nor deleting ones. Why this behaviour in the new release? Why this worked perfectly in previous versions?

Thanks very much!

Here´s is the jta.properties:

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.log_base_dir=${catalina.base}/logs
com.atomikos.icatch.output_dir=${catalina.base}/logs
com.atomikos.icatch.console_log_level=DEBUG
com.atomikos.icatch.lock_logs=false


And here´s the log. I didn´t see any exception..

08-05-20 17:45:31,609 [http-8080-Processor25] ConnectionPool: cannot grow pool as it reached max size: 3
08-05-20 17:45:31,609 [http-8080-Processor25] an AtomikosXAPooledConnection with a SessionHandleState with 0 context(s): updating last time acquired
08-05-20 17:45:31,609 [http-8080-Processor25] an AtomikosXAPooledConnection with a SessionHandleState with 0 context(s): no test query, skipping test
08-05-20 17:45:31,609 [http-8080-Processor25] an AtomikosXAPooledConnection with a SessionHandleState with 0 context(s): creating connection proxy...
08-05-20 17:45:31,609 [http-8080-Processor25] a SessionHandleState with 0 context(s): notifySessionBorrowed
Juan G Send private email
Tuesday, May 20, 2008
 
 
Another thing here..After throwing the exception performing the "commit", if I try to shutdown Tomcat, I think it gets "idle" waiting for something, and I have to kill Tomcat.

If I start the Tomcat server again, I get a recovery error (the datasource name is jdbc/DMADuero):
08-05-20 17:42:58,625 [http-8080-Processor25] USING com.atomikos.icatch.force_shutdown_on_vm_exit = false
08-05-20 17:42:58,671 [http-8080-Processor25] AtomikosDataSourceBean: initializing with [ xaDataSourceClassName=oracle.jdbc.xa.client.OracleXADataSource, uniqueResourceName=jdbc/datasource, maxPoolSize=3, minPoolSize=1, borrowConnectionTimeout=30, maxIdleTime=60, reapTimeout=300, maintenanceInterval=60, testQuery=null, xaProperties={URL=jdbc:oracle:thin:@...:1521:..., user=...., password=...},]
08-05-20 17:42:58,718 [http-8080-Processor25] Configuration: adding resource jdbc/datasource
08-05-20 17:42:58,718 [http-8080-Processor25] Installing recovery service on resource jdbc/datasource
08-05-20 17:42:58,718 [http-8080-Processor25] jdbc/DMADuero: refreshing XAResource...
08-05-20 17:42:59,140 [http-8080-Processor25] jdbc/DMADuero: refreshed XAResource
08-05-20 17:42:59,140 [http-8080-Processor25] recovery initiated for resource jdbc/DMADuero with branchIdentifier 10.120.0.49.tm
08-05-20 17:42:59,265 [http-8080-Processor25] Error in recovery
javax.transaction.xa.XAException
    at oracle.jdbc.xa.OracleXAResource.recover(OracleXAResource.java:705)
    at com.atomikos.datasource.xa.XATransactionalResource.recover(Unknown Source)
    at com.atomikos.datasource.xa.XATransactionalResource.endRecovery(Unknown Source)
    at com.atomikos.icatch.imp.TransactionServiceImp.recover(Unknown Source)
    at com.atomikos.datasource.xa.XATransactionalResource.setRecoveryService(Unknown Source)
    at com.atomikos.icatch.system.Configuration.addResource(Unknown Source)
    at com.atomikos.jdbc.AtomikosDataSourceBean.doInit(Unknown Source)
    at com.atomikos.jdbc.AbstractDataSourceBean.init(Unknown Source)
    at com.atomikos.tomcat.BeanFactory.getObjectInstance(BeanFactory.java:72)
    at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:140)
Juan G Send private email
Wednesday, May 21, 2008
 
 
Another thing: I´ve tested with de DEPRECATED datasource:

 <Resource name="jdbc/datasource"                  auth="Container"                  type="com.atomikos.jdbc.SimpleDataSourceBean"                  factory="org.apache.naming.factory.BeanFactory"                  uniqueResourceName="jdbc/datasource"                                xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource"                  
connectionPoolSize="5"                  connectionTimeout="40"              xaDataSourceProperties="URL=jdbc:oracle:thin:@...:1521:.;user=..;password=..."/>

And it worked perfectly, but the number of connections is always connectionPoolSize +1, don´t know why. I suppose something´s wrong with the new AtomikosDataSourceBean...

Thanks!
Juan G Send private email
Wednesday, May 21, 2008
 
 
Upps it seems I´ve the SOLUTION for this.

I´ve increased the POOL attribute (maxPoolSize) and it worked !

Thanks for read!
Juan G Send private email
Wednesday, May 21, 2008
 
 
Hi,

All this seems to make sense even if a bit disturbing.

The old deprecated pool did not really have an upper connection limit: when the pool was empty and a new connection was requested from your code, it would just open a new database connection.

The new pool takes the maxPoolSize property very strictly: in no way it's going to create more connections than specified in this setting (with the exception of the extra connection used for recovery).

When the pool is exhausted, it will block until a connection can be acquired or until a configurable timeout occurs. This might be the reason why your Tomcat blocked during shutdown.

Finally, using connections in the way you do can quickly deplete the pool as when a connection is acquired and then closed, the pool waits until the transaction is finished until marking that connection as reusable.

in a nutshell, if you do:

ut.begin();

for (int i=0;i<6;i++) {
  c = ds.getConnection();
  c.close();
}

ut.commit();

with a pool configured with max 5 connections, you will reach the limit.

I hope this makes more sense to you now.

Ludovic
Ludovic Orban Send private email
Friday, May 23, 2008
 
 
Ok, I understood. Perhaps you could add another init param for the pool, some attribute like "onExhausted" with some values like "ON_EXHAUSTED_GROW", "ON_EXHAUSTED_BLOCK". This pool behaviour I´m  telling is the same as Apache commons-pool and I think is very important for production environments.

As I said in other post, I have a problem with this connection locking. Perhaps in my proyect we have too many DAO that only does one DB operation each (and this causes many calls to getConnection()), but I think it´s not bad code design (for DAO reuse reasons).

Going back to the deprecated pool is not the solution, because the new pool has very useful functionality (like shrink pool).

Thanks for your reply!
Juan G Send private email
Saturday, May 24, 2008
 
 
Hi,

On your comment to allow fine-tuning of blocking behaviour of the new pools: can't you just set the maxSize to something high enough to prevent blocking?

That would have the same effect as in the old pools while still enabling shrink to minSize.
Guy Pardon Send private email
Monday, June 09, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics