1 Reply Latest reply on Dec 18, 2006 12:31 PM by r_q_d

    JBossAS ejb3 + JTS failed to release database connection whe

      I have a test case to test the JBoss 4.0.5.GA ejb3 with distributed transactions jbossts-full-4.2.2GA on serverA, serverB and serverC. the result shows that the database connection on serverB and serverC did not get released when some exceptions happens on serverB and serverC.

      I attached the source code at the end of this post.

      here is a summary of my test environment and description:

      environment:
      1. JBossAS: JBoss 4.0.5.GA for all configuration
      2. JTS: jbossts-full-4.2.2GA.
      3. Java: java version "1.5.0_09"
      4. Database: Oracle 10g express edition



      test description:
      3 JBoss application servers running on 3 different computers: ServerA, ServerB and ServerC.
      A junit java client connect directly to ServerA, ServerA connect directly to ServerB, serverB connect directly to ServerC.
      Define the datasource file to have maximum 30 connections to database.
      Each server connects to a seperate database, each database has a table, the table structure is:

      Field | Type | Null | Key | Default | Extra
      --------+-------------+------+-----+---------+---------------
      id | int(11) | NO | PRI | NULL | auto_increment
      name | varchar(10) | YES | | NULL |

      The flow goes like this:
      1. junit client send a data list(include record1, record2, record3, record4, record5, record6) to ServerA.
      2. ServerA inserts record1 into database.
      3. ServerA sends data list (include record2, record 3, record 4, record 5) to ServerB.
      4. ServerB inserts record2 into database.
      5. ServerB sends data list (include record3, record4) to ServerC.
      6. ServerC insert record3 into database.
      7. ServerC insert record4 into database.
      8. ServerB inserts record5 into database.
      9. ServerA inserts record6 into database.

      The junit java client can control where the exception happens by passing invalid data( e.g. field is too long) in data list.

      My test reveils that the distributed transactions is working fine if the transaction can commit or something wrong happens on the first server (ServerA), If something wrong happens on the second or third server, the overall data did not get committed to the database as expected, but the database connection to ServerB and ServerC does not get released and becomes not available. when I run the test several times, the database connections will eventually used up and no managed connection is available.

      I followed the JBossJTS jts_install.txt, configured com.arjuna.ats.internal.jta.recovery.jts.XARecoveryModule as RecoveryModule as indicated from http://jira.jboss.com/jira/browse/JBTM-170, config com.arjuna.ats.arjuna.xa.nodeIdentifier to use unique id for each computer.

      Here are errors show up at client side:

      javax.ejb.EJBTransactionRolledbackException: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
       at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:93)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
       at org.jboss.aspects.tx.TxInterceptor$Mandatory.invoke(TxInterceptor.java:305)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:67)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
       at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
       at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
      Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
       at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:647)
       at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:73)
       at jtstest.ProcessorSessionHelper.getLocalTotal(ProcessorSessionHelper.java:117)
       at jtstest.ProcessorSessionHelper.getTotalNumberOfRecords(ProcessorSessionHelper.java:82)
       at jtstest.ProcessorSessionImplB.getTotalNumberOfRecords(ProcessorSessionImplB.java:27)
       at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
       at org.jboss.aspects.tx.TxInterceptor$Mandatory.invoke(TxInterceptor.java:305)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:67)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
       at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
       at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
       at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
       at org.jboss.remoting.Client.invoke(Client.java:525)
       at org.jboss.remoting.Client.invoke(Client.java:488)
       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
       at $Proxy79.getTotalNumberOfRecords(Unknown Source)
       at jtstest.ProcessorSessionHelper.getTotalNumberOfRecords(ProcessorSessionHelper.java:99)
       at jtstest.ProcessorSessionImplA.getTotalNumberOfRecords(ProcessorSessionImplA.java:26)
       at sun.reflect.GeneratedMethodAccessor94.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
       at org.jboss.aspects.tx.TxInterceptor$RequiresNew.invoke(TxInterceptor.java:262)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
       at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
       at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
       at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
       at org.jboss.remoting.Client.invoke(Client.java:525)
       at org.jboss.remoting.Client.invoke(Client.java:488)
       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
       at $Proxy0.getTotalNumberOfRecords(Unknown Source)
       at jtstest.TestJtsWithTwoServers.testFailureRecord3OnBFailedToInsert(TestJtsWithTwoServers.java:105)
       at jtstest.TestJtsWithTwoServers.testRunSeveralTimesForRecord3OnBFailedToInsert(TestJtsWithTwoServers.java:145)
       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:585)
       at junit.framework.TestCase.runTest(TestCase.java:154)
       at junit.framework.TestCase.runBare(TestCase.java:127)
       at junit.framework.TestResult$1.protect(TestResult.java:106)
       at junit.framework.TestResult.runProtected(TestResult.java:124)
       at junit.framework.TestResult.run(TestResult.java:109)
       at junit.framework.TestCase.run(TestCase.java:118)
       at junit.framework.TestSuite.runTest(TestSuite.java:208)
       at junit.framework.TestSuite.run(TestSuite.java:203)
       at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
       at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
      Caused by: org.hibernate.exception.GenericJDBCException: Cannot open connection
       at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
       at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
       at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
       at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
       at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:420)
       at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
       at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
       at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1560)
       at org.hibernate.loader.Loader.doQuery(Loader.java:661)
       at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
       at org.hibernate.loader.Loader.doList(Loader.java:2144)
       at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2028)
       at org.hibernate.loader.Loader.list(Loader.java:2023)
       at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:393)
       at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
       at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
       at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
       at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
       at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64)
       at jtstest.ProcessorSessionHelper.getLocalTotal(ProcessorSessionHelper.java:117)
       at jtstest.ProcessorSessionHelper.getTotalNumberOfRecords(ProcessorSessionHelper.java:82)
       at jtstest.ProcessorSessionImplB.getTotalNumberOfRecords(ProcessorSessionImplB.java:27)
       at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
       at org.jboss.aspects.tx.TxInterceptor$Mandatory.invoke(TxInterceptor.java:305)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:67)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
       at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
       at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
      Caused by: org.jboss.util.NestedSQLException: Could not create connection; - nested throwable: (java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE
      ); - nested throwable: (org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE
      ))
       at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:94)
       at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:47)
       at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:417)
       ... 50 more
      Caused by: org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE
      )
       at org.jboss.resource.adapter.jdbc.xa.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java:164)
       at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.createConnectionEventListener(InternalManagedConnectionPool.java:565)
       at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.getConnection(InternalManagedConnectionPool.java:250)
       at org.jboss.resource.connectionmanager.JBossManagedConnectionPool$BasePool.getConnection(JBossManagedConnectionPool.java:529)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2.getManagedConnection(BaseConnectionManager2.java:341)
       at org.jboss.resource.connectionmanager.TxConnectionManager.getManagedConnection(TxConnectionManager.java:301)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:396)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:842)
       at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:88)
       ... 52 more
      Caused by: java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE
      
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:380)
       at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
       at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:441)
       at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
       at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
       at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:839)
       at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:389)
       at oracle.jdbc.xa.client.OracleXADataSource.getPooledConnection(OracleXADataSource.java:557)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:177)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:163)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:112)
       at org.jboss.resource.adapter.jdbc.xa.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java:156)
       ... 60 more
      


      Here is the error shows up at the server B:

      12:06:01,734 INFO [loggerI18N] [com.arjuna.ats.internal.jta.recovery.info.secondpass] JTS XARecoveryModule - second pass
      12:06:39,734 WARN [JBossManagedConnectionPool] Unable to fill pool
      org.jboss.resource.JBossResourceException: Could not create connection; - nested
       throwable: (java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE)
       at org.jboss.resource.adapter.jdbc.xa.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java:164)
       at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.createConnectionEventListener(InternalManagedConnectionPool.java:565)
       at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.fillToMin(InternalManagedConnectionPool.java:512)
       at org.jboss.resource.connectionmanager.PoolFiller.run(PoolFiller.java:74)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: java.sql.SQLException: Listener refused the connection with the following error:
      ORA-12519, TNS:no appropriate service handler found
      The Connection descriptor used by the client was:
      localhost:1521:XE
      
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:380)
       at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
       at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:441)
       at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
       at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
       at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:839)
       at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:389)
       at oracle.jdbc.xa.client.OracleXADataSource.getPooledConnection(OracleXADataSource.java:557)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:177)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:163)
       at oracle.jdbc.xa.client.OracleXADataSource.getXAConnection(OracleXADataSource.java:112)
       at org.jboss.resource.adapter.jdbc.xa.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java:156)
       ... 4 more
      12:08:01,734 INFO [arjLogger] Periodic recovery - first pass <Mon, 18 Dec 2006
      12:08:01>
      12:08:01,734 INFO [arjLogger] StatusModule: first pass
      



      Here is the test code:

      TestJtsWithTwoServers
      package jtstest;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import jtstest.AddressInfo;
      import jtstest.DataPack;
      import jtstest.EjbUtil;
      import jtstest.JndiInfo;
      import jtstest.ProcessorSessionBean;
      import junit.framework.TestCase;
      
      
      public class TestJtsWithTwoServers extends TestCase {
       String myServer = "10.60.55.130";
       String otherServer = "10.60.55.140";
      
       String serverA = myServer;
       String serverB = otherServer;
      
       JndiInfo jndiInfoA;
       JndiInfo jndiInfoB;
       List<JndiInfo> servers;
       private static final int NUMBER_OF_TIMES_TO_RUN = 10;
      
       private ProcessorSessionBean getEjb() throws Exception {
       return new EjbUtil().getEjb(jndiInfoA);
       }
      
       protected void setUp() throws Exception {
       jndiInfoA = new JndiInfo("ProcessorSessionImplA/remote", serverA);
       jndiInfoB = new JndiInfo("ProcessorSessionImplB/remote", serverB);
      
       servers = new ArrayList<JndiInfo>();
       servers.add(jndiInfoA);
       servers.add(jndiInfoB);
      
       }
      
       private DataPack createDataPack(JndiInfo theJndiInfo, String name1, String name2) {
       return new DataPack(theJndiInfo, new AddressInfo(name1), new AddressInfo(name2));
       }
      
       public void testAllSuccess() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name4"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2","name3"));
      
       getEjb().createAddressInfo(dataPacks);
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal+4, newTotal);
       }
      
       public void testFailureRecord1OnAFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "nameToInsertIsTooLongForDB!---------------------", "name4"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name3"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord2OnBFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name4"));
       dataPacks.add(1, createDataPack(jndiInfoB, "nameToInsertIsTooLongForDB!---------------------", "name3"));
      
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord3OnBFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name4"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "nameToInsertIsTooLongForDB!---------------------"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord4OnAFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "nameToInsertIsTooLongForDB!---------------------"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name3"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testRunSeveralTimesForRecord1OnAFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord1OnAFailedToInsert();
       }
       }
      
      
       public void testRunSeveralTimesForRecord2OnBFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord2OnBFailedToInsert();
       }
       }
      
       //This is the only tests that fails
       public void testRunSeveralTimesForRecord3OnBFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord3OnBFailedToInsert();
       }
       }
      
       public void testRunSeveralTimesForRecord4OnAFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord4OnAFailedToInsert();
       }
       }
      
      }
      


      Here is my ejb related classes:

      AddressInfo
      package jtstest;
      
      import java.io.Serializable;
      
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;
      import javax.persistence.Table;
      
      @Entity
      @Table(name="address_info")
      public class AddressInfo implements Serializable {
      
       private static final long serialVersionUID = 2357882637962314812L;
       private Integer id;
       private String name;
      
       public AddressInfo() {
       }
      
       public AddressInfo (String theName) {
       name = theName;
       }
      
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       public Integer getId() {
       return id;
       }
       public void setId(Integer id) {
       this.id = id;
       }
      
       @Column(name="name", length=10)
       public String getName() {
       return name;
       }
       public void setName(String name) {
       this.name = name;
       }
      
       public boolean equals(Object o) {
       if (!( o instanceof AddressInfo)) {
       return false;
       }
      
       AddressInfo other = (AddressInfo) o;
      
       if (name.equals(other.name)) {
       return true;
       }
       return false;
       }
      }
      


      DataPack
      package jtstest;
      
      import java.io.Serializable;
      
      public class DataPack implements Serializable {
       private static final long serialVersionUID = -813804649171757870L;
      
       private JndiInfo jndiInfo;
       private AddressInfo a;
       private AddressInfo b;
      
       public DataPack (JndiInfo theJndiInfo, AddressInfo theA, AddressInfo theB) {
       jndiInfo = theJndiInfo;
       a = theA;
       b = theB;
       }
      
       public AddressInfo getA() {
       return a;
       }
       public void setA(AddressInfo a) {
       this.a = a;
       }
       public AddressInfo getB() {
       return b;
       }
       public void setB(AddressInfo b) {
       this.b = b;
       }
      
       public JndiInfo getJndiInfo() {
       return jndiInfo;
       }
      
       public void setJndiInfo(JndiInfo jndiInfo) {
       this.jndiInfo = jndiInfo;
       }
      }
      


      EjbUtil
      package jtstest;
      
      import java.io.Serializable;
      import java.util.Properties;
      
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      public class EjbUtil implements Serializable{
       private static final long serialVersionUID = 6369596478122255296L;
      
       public ProcessorSessionBean getEjb(JndiInfo jndiInfo) throws NamingException {
       System.out.println(" jndiInfo="+jndiInfo.toString());
       ProcessorSessionBean ejb = (ProcessorSessionBean) getInitialContext(jndiInfo.getIpAddress()).lookup(jndiInfo.getJndiName());
       System.out.println(ejb.getClass().getName()+" jndiInfo="+jndiInfo.toString());
       return ejb;
       }
      
       private InitialContext getInitialContext(String serverId) throws NamingException {
       Properties props = new Properties();
      
       props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
       props.setProperty("java.naming.provider.url", serverId+":1099");
       props.setProperty("java.naming.factory.url.pkgs", "org.jnp.naming");
      
       return new InitialContext(props);
       }
      
      }
      


      JndiInfo
      package jtstest;
      
      import java.io.Serializable;
      
      public class JndiInfo implements Serializable {
       private static final long serialVersionUID = -3305133197382755505L;
       private String jndiName;
       private String ipAddress;
      
       public JndiInfo(String name, String ip) {
       jndiName = name;
       ipAddress = ip;
       }
      
       public String getIpAddress() {
       return ipAddress;
       }
       public void setIpAddress(String ipAddress) {
       this.ipAddress = ipAddress;
       }
       public String getJndiName() {
       return jndiName;
       }
       public void setJndiName(String jndiName) {
       this.jndiName = jndiName;
       }
      
       public String toString() {
       return "JndiInfo[ip="+ipAddress+", name="+jndiName+"]";
       }
      
      }
      


      ProcessorSessionBean
      package jtstest;
      
      import java.io.Serializable;
      import java.util.List;
      
      import javax.ejb.Remote;
      
      
      @Remote
      public interface ProcessorSessionBean extends Serializable{
      
       public void createAddressInfo(List<DataPack> dataPacks);
      
       public int getTotalNumberOfRecords(List<JndiInfo> ips);
      }
      


      ProcessorSessionHelper
      package jtstest;
      
      import java.io.Serializable;
      import java.util.ArrayList;
      import java.util.List;
      
      import javax.ejb.EJBException;
      import javax.naming.NamingException;
      import javax.persistence.EntityManager;
      import javax.persistence.Query;
      
      
      public class ProcessorSessionHelper implements Serializable{
      
       private static final long serialVersionUID = 8003271655921801619L;
      
       public void createAddressInfo(EntityManager entityManager, List<DataPack> dataPacks){
       try {
       DataPack myPack = dataPacks.get(0);
      
       if(myPack.getA()!=null && myPack.getA().getName()!=null) {
       insertRecord(entityManager, myPack.getA());
       }
      
       if(dataPacks.size()>1){
       askAnotherServerToCreate(entityManager, dataPacks);
       }
      
       if(myPack.getB()!=null && myPack.getB().getName()!=null) {
       insertRecord(entityManager, myPack.getB());
       }
      
       } catch (NamingException e) {
       throw new EJBException(e.toString());
       }
       }
      
       private void askAnotherServerToCreate(EntityManager entityManager, List<DataPack> dataPacks) throws NamingException {
       System.out.println("askAnotherServerToCreate begin");
       List<DataPack> newList = new ArrayList<DataPack>();
       for(int i=1;i<dataPacks.size();i++){
       newList.add(dataPacks.get(i));
       }
       System.out.println("newList Size = " + newList.size());
       JndiInfo jndiInfo = dataPacks.get(1).getJndiInfo();
       ProcessorSessionBean serverB = new EjbUtil().getEjb(new JndiInfo(jndiInfo.getJndiName(), jndiInfo.getIpAddress()));
       serverB.createAddressInfo(newList);
       System.out.println("askAnotherServerToCreate end");
       }
      
       private AddressInfo insertRecord(EntityManager entityManager, AddressInfo info1) {
       String name = info1.getName();
       if(name!=null && name.length()>10) {
       throw new EJBException("name("+name+") is longer than 10 characters");
       }
      
       AddressInfo info = new AddressInfo();
       info.setName(name);
       entityManager.persist(info);
       return info;
       }
      
       public int getTotalNumberOfRecords(EntityManager entityManager, List<JndiInfo> ips) {
       System.out.println("findAll begin");
       try {
       int total = getLocalTotal(entityManager);
      
       if(ips.size()>1){
       List<JndiInfo> newJndiInfo = new ArrayList<JndiInfo>();
       for (int i = 1; i < ips.size(); i++) {
       newJndiInfo.add(ips.get(i));
       }
      
       ProcessorSessionBean serverB = new EjbUtil().getEjb(newJndiInfo.get(0));
      
       total+=serverB.getTotalNumberOfRecords(newJndiInfo);
       }
       return total;
       } catch (NamingException e) {
       e.printStackTrace();
       return 0;
       }
       }
      
       @SuppressWarnings("unchecked")
       private int getLocalTotal(EntityManager entityManager){
       Query query = entityManager.createQuery("select a from AddressInfo a");
       int size = query.getResultList().size();
       return size;
       }
      }
      


      ProcessorSessionImplA
      package jtstest;
      
      import java.util.List;
      
      import javax.ejb.Stateless;
      import javax.ejb.TransactionAttribute;
      import javax.ejb.TransactionAttributeType;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      @Stateless
      public class ProcessorSessionImplA implements ProcessorSessionBean {
      
       private static final long serialVersionUID = 7226720566253076962L;
      
       @PersistenceContext(unitName="OracleDS")
       private EntityManager entityManager;
      
       @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public void createAddressInfo(List<DataPack> dataPacks){
       new ProcessorSessionHelper().createAddressInfo(entityManager, dataPacks);
       }
      
       @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public int getTotalNumberOfRecords(List<JndiInfo> ips) {
       return new ProcessorSessionHelper().getTotalNumberOfRecords(entityManager, ips);
       }
      
      }
      


      ProcessorSessionImplB
      package jtstest;
      
      import java.util.List;
      
      import javax.ejb.EJBException;
      import javax.ejb.Stateless;
      import javax.ejb.TransactionAttribute;
      import javax.ejb.TransactionAttributeType;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      @Stateless
      public class ProcessorSessionImplB implements ProcessorSessionBean{
      
       private static final long serialVersionUID = 7112486607575606949L;
      
       @PersistenceContext(unitName="OracleDS")
       private EntityManager entityManager;
      
       @TransactionAttribute(TransactionAttributeType.MANDATORY)
       public void createAddressInfo(List<DataPack> dataPacks){
       new ProcessorSessionHelper().createAddressInfo(entityManager, dataPacks);
       }
      
       @TransactionAttribute(TransactionAttributeType.MANDATORY)
       public int getTotalNumberOfRecords(List<JndiInfo> ips) {
       return new ProcessorSessionHelper().getTotalNumberOfRecords(entityManager, ips);
       }
      
      }
      


      ProcessorSessionImplC
      package jtstest;
      
      import java.util.List;
      
      import javax.ejb.EJBException;
      import javax.ejb.Stateless;
      import javax.ejb.TransactionAttribute;
      import javax.ejb.TransactionAttributeType;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      @Stateless
      public class ProcessorSessionImplC implements ProcessorSessionBean{
      
       private static final long serialVersionUID = 7112486607575606949L;
      
       @PersistenceContext(unitName="OracleDS")
       private EntityManager entityManager;
      
       @TransactionAttribute(TransactionAttributeType.MANDATORY)
       public void createAddressInfo(List<DataPack> dataPacks){
       new ProcessorSessionHelper().createAddressInfo(entityManager, dataPacks);
       }
      
       @TransactionAttribute(TransactionAttributeType.MANDATORY)
       public int getTotalNumberOfRecords(List<JndiInfo> ips) {
       return new ProcessorSessionHelper().getTotalNumberOfRecords(entityManager, ips);
       }
      
      }
      


      Here is my datasource file:

      <datasources>
       <xa-datasource>
       <jndi-name>XAOracleDS</jndi-name>
       <track-connection-by-tx/>
       <isSameRM-override-value>false</isSameRM-override-value>
       <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
       <xa-datasource-property name="URL">jdbc:oracle:thin:@10.60.55.130:1521:XE</xa-datasource-property>
       <xa-datasource-property name="User">dt1</xa-datasource-property>
       <xa-datasource-property name="Password">dt1</xa-datasource-property>
       <!--valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name-->
       <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
       <no-tx-separate-pools/>
       <max-pool-size>30</max-pool-size>
       <min-pool-size>10</min-pool-size>
      
       <metadata>
       <type-mapping>Oracle9i</type-mapping>
       </metadata>
       </xa-datasource>
      
       <mbean code="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter"
       name="jboss.jca:service=OracleXAExceptionFormatter">
       <depends optional-attribute-name="TransactionManagerService">jboss:service=TransactionManager</depends>
       </mbean>
      
      </datasources>
      


      Here is my persistence.xml:

      <persistence>
       <persistence-unit name="OracleDS" transaction-type="JTA">
       <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <jta-data-source>java:XAOracleDS</jta-data-source>
       <properties>
       <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
       <property name="hibernate.show_sql" value="true"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
       <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
       <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
       </properties>
       </persistence-unit>
      </persistence>
      


      Here is another test case:

      TestJtsWithThreeServers
      package jtstest;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import jtstest.AddressInfo;
      import jtstest.DataPack;
      import jtstest.EjbUtil;
      import jtstest.JndiInfo;
      import jtstest.ProcessorSessionBean;
      import junit.framework.TestCase;
      
      
      public class TestJtsWithThreeServers extends TestCase {
      
       String myServer = "10.60.55.130";
       String otherServer = "10.60.55.140";
       String lastServer = "10.60.55.110";
      
       String serverA = myServer;
       String serverB = otherServer;
       String serverC = lastServer;
      
       JndiInfo jndiInfoA;
       JndiInfo jndiInfoB;
       JndiInfo jndiInfoC;
       List<JndiInfo> servers;
       private static final int NUMBER_OF_TIMES_TO_RUN = 35;
      
       private ProcessorSessionBean getEjb() throws Exception {
       return new EjbUtil().getEjb(jndiInfoA);
       }
      
       protected void setUp() throws Exception {
       jndiInfoA = new JndiInfo("ProcessorSessionImplA/remote", serverA);
       jndiInfoB = new JndiInfo("ProcessorSessionImplB/remote", serverB);
       jndiInfoC = new JndiInfo("ProcessorSessionImplC/remote", serverC);
      
       servers = new ArrayList<JndiInfo>();
       servers.add(jndiInfoA);
       servers.add(jndiInfoB);
       servers.add(jndiInfoC);
      
       }
      
      
       private DataPack createDataPack(JndiInfo theJndiInfo, String name1, String name2) {
       return new DataPack(theJndiInfo, new AddressInfo(name1), new AddressInfo(name2));
       }
      
       public void testAllSuccess() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4"));
      
       getEjb().createAddressInfo(dataPacks);
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal+6, newTotal);
       }
      
       public void testFailureRecord1OnAFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1---------------------", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord2OnBFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2---------------------", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
       public void testFailureRecord3OnCFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3---------------------","name4"));
      
       try {
       System.out.println("3----------------------");
       getEjb().createAddressInfo(dataPacks);
       System.out.println("4----------------------");
       fail("should not go to here");
       }catch (Throwable e) {
       System.out.println("5----------------------");
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord4OnCFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4---------------------"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord5OnBFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5---------------------"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       public void testFailureRecord6OnAFailedToInsert() throws Exception {
       int oldTotal = getEjb().getTotalNumberOfRecords(servers);
      
       List<DataPack> dataPacks = new ArrayList<DataPack>();
       dataPacks.add(0, createDataPack(jndiInfoA, "name1", "name6---------------------"));
       dataPacks.add(1, createDataPack(jndiInfoB, "name2", "name5"));
       dataPacks.add(2, createDataPack(jndiInfoC, "name3", "name4"));
      
       try {
       getEjb().createAddressInfo(dataPacks);
       fail("should not go to here");
       }catch (Throwable e) {
       }
      
       int newTotal = getEjb().getTotalNumberOfRecords(servers);
       assertEquals(oldTotal, newTotal);
       }
      
       //This one works.
       public void testRunSeveralTimesForRecord1OnAFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord1OnAFailedToInsert();
       }
       }
      
       //This one works.
       public void testRunSeveralTimesForRecord2OnBFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord2OnBFailedToInsert();
       }
       }
      
       //This one will fail
       public void testRunSeveralTimesForRecord3OnCFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord3OnCFailedToInsert();
       }
       }
      
       //This one will fail
       public void testRunSeveralTimesForRecord4OnCFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord4OnCFailedToInsert();
       }
       }
      
       //This one will fail
       public void testRunSeveralTimesForRecord5OnBFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord5OnBFailedToInsert();
       }
       }
      
       //This test passes.
       public void testRunSeveralTimesForRecord6OnAFailedToInsert() throws Exception {
       for(int i=0;i<NUMBER_OF_TIMES_TO_RUN;i++) {
       System.out.println(""+i);
       testFailureRecord6OnAFailedToInsert();
       }
       }
      
      }
      



        • 1. Re: JBossAS ejb3 + JTS failed to release database connection

          I rewrote the flow like following so that it can be easy to understand.

          1. junit client send a data list(include record1, record2, record3, record4, record5, record6) to ServerA.
          2. ServerA inserts record1 into database.
          3. ServerA sends data list (include record2, record 3, record 4, record 5) to ServerB.
          4. ServerB inserts record2 into database.
          5. ServerB sends data list (include record3, record4) to ServerC.
          6. ServerC insert record3 into database.
          7. ServerC insert record4 into database.
          8. ServerB inserts record5 into database.
          9. ServerA inserts record6 into database.