3 Replies Latest reply: Apr 8, 2013 2:46 AM by 915279 RSS

    java.sql.SQLException: Statement cancelled, probably by transaction timing

    915279
      Hi all,

      I have a problem with transaction handling over 2 applications. I have 2 EAR files (*A.ear* and B.ear) which are deployed on a WLS 12.1. The WLS contains a XA datasource which is connected to a Oracle XE database. Both applications are using the same datasource. The datasource is configured to use the driver oracle.jdbc.xa.client.OracleXADataSource.

      EAR A contains a Remote EJB which is is calling a local EJB. The local EJB calls a Remote EJB from EAR B.
      Here is an example how the code looks like:
      @Remote
      @Stateless(mappedName = "AnyRemote", name = "AnyRemote")
      public class AnyRemoteBean implements AnyRemote {
      
          @EJB
          private AnyLocal anyLocal;
      
          @Override
          public void doIt() {
              anyLocal.doSomething();
          }
      }
      @Local
      @Stateless(mappedName = "AnyLocal", name = "AnyLocal")
      public class AnyLocalBean implements AnyLocal {
      
          @PersistenceContext(unitName = "A")
          private EntityManager entityManager;
      
          @EJB(mappedName = "AnyCompositeService")
          private AnyCompositeService anyCompositeService;
      
          @Override
          @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
          public boolean doSomething() {
                  try {
                       // do some stuff and save to database within another local EJB
                      anyCompositeService.doSomethingOnEAR_B();
                      return true;
                  } catch (final AnyException e) {
                      LOGGER.error("doSomething failed", e);
                      return false;
                  }
              }
          }
      
          @Override
          @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
          public boolean stayOnEar_A() {
                  // do some stuff and save to database within another local EJB
                  return true;
              }
          }
      
      }
      AnyCompositeService located in EAR B looks like this:
      @Remote
      @Stateless(mappedName = "AnyCompositeService ", name = "AnyCompositeService ")
      public class AnyCompositeServiceBean implements AnyCompositeService {
      
          @Override
          public boolean doSomethingOnEAR_B() throws AnyException {
              // do some calls to some local EJBs and some other remote EJBs and save something to database
              return true;
          }
      }
      In this process of EAR B I'm using the entitiy manager:
          @PersistenceContext(unitName = "B")
          private EntityManager entityManager;
      persistence.xml for EAR A looks like this
          <persistence-unit name="A" transaction-type="JTA">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <jta-data-source>MyDatasource</jta-data-source>
             <!-- some entities -->
              <properties>
                  <property name="hibernate.transaction.jta.platform"
                      value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />
                  <property name="hibernate.max_fetch_depth" value="3" />
                  <property name="hibernate.connection.characterEncoding" value="UTF-8" />
                  <property name="hibernate.connection.charSet" value="UTF-8" />
                  <property name="hibernate.connection.useUnicode" value="true" />
                  <property name="hibernate.default_batch_fetch_size" value="20" />
              </properties>
          </persistence-unit>
      </persistence>
      persistence.xml for EAR B looks like this
          <persistence-unit name="B" transaction-type="JTA">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <jta-data-source>MyDatasource</jta-data-source>
             <!-- some entities -->
              <properties>
                  <property name="hibernate.transaction.jta.platform"
                      value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />
                  <property name="hibernate.max_fetch_depth" value="3" />
                  <property name="hibernate.connection.characterEncoding" value="UTF-8" />
                  <property name="hibernate.connection.charSet" value="UTF-8" />
                  <property name="hibernate.connection.useUnicode" value="true" />
                  <property name="hibernate.default_batch_fetch_size" value="20" />
              </properties>
          </persistence-unit>
      </persistence>
      As you can see the method doSomething() defines the transaction attribute TransactionAttributeType.REQUIRES_NEW.
      When I execute AnyRemote.doIt() I get the following exception:
      Caused By: java.sql.SQLException: Statement cancelled, probably by transaction timing out
           at weblogic.jdbc.wrapper.Statement.postInvocationHandler(Statement.java:69)
           at weblogic.jdbc.wrapper.PreparedStatement_oracle_jdbc_driver_OraclePreparedStatementWrapper.clearBatch(Unknown Source)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
           at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
           at $Proxy452.clearBatch(Unknown Source)
           at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.releaseStatements(AbstractBatchImpl.java:163)
           at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.release(AbstractBatchImpl.java:197)
           at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:139)
           at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.close(TransactionCoordinatorImpl.java:276)
           at org.hibernate.internal.SessionImpl.close(SessionImpl.java:349)
           at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:137)
           at weblogic.persistence.TransactionalEntityManagerProxyImpl.close(TransactionalEntityManagerProxyImpl.java:117)
           at weblogic.persistence.BasePersistenceContextProxyImpl$PersistenceContextCloser.afterCompletion(BasePersistenceContextProxyImpl.java:213)
           at weblogic.transaction.internal.ServerSCInfo.doAfterCompletion(ServerSCInfo.java:1068)
           at weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(ServerSCInfo.java:1012)
           at weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions(ServerTransactionImpl.java:3074)
           at weblogic.transaction.internal.ServerTransactionImpl.afterRolledBackStateHousekeeping(ServerTransactionImpl.java:2954)
           at weblogic.transaction.internal.ServerTransactionImpl.setRolledBack(ServerTransactionImpl.java:2930)
           at weblogic.transaction.internal.ServerTransactionImpl.globalRetryRollback(ServerTransactionImpl.java:3172)
           at weblogic.transaction.internal.ServerTransactionImpl.globalRollback(ServerTransactionImpl.java:2920)
           at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:374)
           at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:268)
           at weblogic.ejb.container.internal.BaseLocalObject.postInvoke1(BaseLocalObject.java:332)
           at weblogic.ejb.container.internal.BaseLocalObject.__WL_postInvokeTxRetry(BaseLocalObject.java:202)
           at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:44)
      As long as the process only calls EJBs from EAR A only there is no issue. But if the process calls the method doSomethingOnEAR_B() on EAR B the call fails with above exception. If the process throws AnyException the rollback takes place as expected for transaction in EAR B and EAR A.

      Does anybody know what is the issue here? Is there any configuration I have overseen?