[ 
https://issues.apache.org/jira/browse/ARIES-1279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14243292#comment-14243292
 ] 

Aleksey Sushko commented on ARIES-1279:
---------------------------------------

Study the trace log

{quote}
 TRACE AbstractSinglePoolConnectionInterceptor  106 - returning connection null 
for MCI ManagedConnectionInfo: 
org.apache.geronimo.connector.outbound.ManagedConnectionInfo@5d36f93f. mc: 
org.tranql.connector.jdbc.ManagedJDBCConnection@4425c6e8] and MC 
org.tranql.connector.jdbc.ManagedJDBCConnection@4425c6e8 to pool 
org.apache.geronimo.connector.outbound.SinglePoolConnectionInterceptor@4ee42af2
{quote}

The magazine goes information about that option 
connectionInfo.getConnectionHandle() empty (is null).

Further, there is a call another method
{code}
boolean releasePermit = internalReturn(connectionInfo, connectionReturnAction);
{code}

There has not destroyed connectionInfo.getConnectionHandle(), and something 
else. Is this
{code}
ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
ManagedConnection mc = mci.getManagedConnection();
mc.physicalConnection; // !!!
{code}

I think that it was necessary to sort in ManagedConnection all handlers. And to 
close only those that match the value
connectionInfo.getConnectionHandle().

My opinion. ManagedConnection not revealed to the compound. The current 
connection is not closed.
The procedure for closing the transaction will close all by yourself attached 
connection. Just as it is done
when making a transaction.

Below shows the stack action of closing the current connection
{quote}
Thread [main] (Suspended)
        ManagedJDBCConnection(AbstractManagedConnection<T,U>).cleanup() line: 66
        ManagedJDBCConnection.cleanup() line: 128
        
SinglePoolConnectionInterceptor(AbstractSinglePoolConnectionInterceptor).internalReturn(ConnectionInfo,
 ConnectionReturnAction) line: 151
        
SinglePoolConnectionInterceptor(AbstractSinglePoolConnectionInterceptor).returnConnection(ConnectionInfo,
 ConnectionReturnAction) line: 129
        TransactionEnlistingInterceptor.returnConnection(ConnectionInfo, 
ConnectionReturnAction) line: 113
        TransactionCachingInterceptor.returnConnection(ConnectionInfo, 
ConnectionReturnAction) line: 119
        ConnectionHandleInterceptor.returnConnection(ConnectionInfo, 
ConnectionReturnAction) line: 71
        TCCLInterceptor.returnConnection(ConnectionInfo, 
ConnectionReturnAction) line: 50
        ConnectionTrackingInterceptor.returnConnection(ConnectionInfo, 
ConnectionReturnAction) line: 91
        
GeronimoConnectionEventListener.connectionErrorOccurred(ConnectionEvent) line: 
95
        
ManagedJDBCConnection(AbstractManagedConnection<T,U>).unfilteredConnectionError(Exception)
 line: 126
        
ManagedJDBCConnection(AbstractManagedConnection<T,U>).connectionError(Exception)
 line: 115
        ConnectionHandle.connectionError(SQLException) line: 112
        ConnectionHandle.prepareStatement(String) line: 243
        TestRollback.internalProcess(Connection) line: 119
        TestRollback.internalProcess(DataSource) line: 100
        TestRollback.test() line: 76
        NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not 
available [native method]
        NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57
        DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
        Method.invoke(Object, Object...) line: 606
        FrameworkMethod$1.runReflectiveCall() line: 47
        FrameworkMethod$1(ReflectiveCallable).run() line: 12
        FrameworkMethod.invokeExplosively(Object, Object...) line: 44
        InvokeMethod.evaluate() line: 17
        BlockJUnit4ClassRunner(ParentRunner<T>).runLeaf(Statement, Description, 
RunNotifier) line: 271
        BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 70
        BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 50
        ParentRunner$3.run() line: 238
        ParentRunner$1.schedule(Runnable) line: 63
        BlockJUnit4ClassRunner(ParentRunner<T>).runChildren(RunNotifier) line: 
236
        ParentRunner<T>.access$000(ParentRunner, RunNotifier) line: 53
        ParentRunner$2.evaluate() line: 229
        RunBefores.evaluate() line: 26
        RunAfters.evaluate() line: 27
        BlockJUnit4ClassRunner(ParentRunner<T>).run(RunNotifier) line: 309
        JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 
50
        TestExecution.run(ITestReference[]) line: 38
        RemoteTestRunner.runTests(String[], String, TestExecution) line: 459
        RemoteTestRunner.runTests(TestExecution) line: 675
        RemoteTestRunner.run() line: 382
        RemoteTestRunner.main(String[]) line: 192
{quote}

In the old project, org.apache.aries.transaction.wrappers, not for this error.
XADatasourceEnlistingWrapper connects the listener TransactionListener
{code}
transaction.enlistResource(xaResource);
transaction.registerSynchronization(new TransactionListener(key));
{code}

In the new project, org.apache.aries.transaction.jdbc, there is no such 
listener.
TransactionListener closes the previously closed resources.

Yeshe was one handler, ConnectionWrapper. He has refused to close the 
connection,
when it is attached to the transaction.

Without these handlers we have unpleasant picture.
{code}
TransactionManager tm;
DataSource ds;
for(i = 0; i < (int) 1E4; i++) {
  tm.begin();
  Connection con = ds.getConnection();
  // without con.close();
  tm.commit();
}
{code}
We get an overflow of open connections.

Making an example of a textbook
{code}
TransactionManager tm;
DataSource ds;
for(i = 0; i < (int) 1E4; i++) {
  tm.begin();
  try {
    Connection con = ds.getConnection();
    ...
    throw new Exception("busines error");
    ...
    con.close();

    tm.commit();
  } catch(Exception) {
    tm.rollback();
  }
}
{code}
We get an overflow of open connections.
Method tm.rollback() clear all XAResurce. But remained open connections.

Fix the sample code
{code}
TransactionManager tm;
DataSource ds;
for(i = 0; i < (int) 1E4; i++) {
  tm.begin();
  try {
    Connection con = ds.getConnection();

    try {
      ...
      throw new Exception("busines error");
      ...
    } finnaly {
      con.close();
    }

    tm.commit();
  } catch(Exception) {
    tm.rollback();
  }
}
{code}
All connections are closed.

Note that the project org.apache.aries.transaction.wrappers no problems with 
missing connections.
ConnectionWrapper not block the connection and TransactionListener closes the 
connection.
I'm not saying that this implementation was correct. But it works well for the 
book. First Example no errors.

In the new project connection rises from tranql pool and returns to the same. 
Academically it right.
All the same, the right will be the third, the corrected code tutorial.

Now consider an example where the compound itself generates an error.
We agree that there is no table in the database with the name MYTABLE.
{code}
con.prepareStatement("SELECT * FROM MYTABLE");
{code}
Implementation of this line calls the emergency closure of the physical 
connection.
Current connection enters the pool of pending connections in the current 
transaction.
This theoretically means that the next connection request from this DataSource 
will return this connection.
In the example code, we have received the compound and continue to work with 
him.
But the attempt to perform any action on this connection will fail.
This happens when a method is called rollback.


> Transaction does not work on error SQLException
> -----------------------------------------------
>
>                 Key: ARIES-1279
>                 URL: https://issues.apache.org/jira/browse/ARIES-1279
>             Project: Aries
>          Issue Type: Bug
>          Components: Transaction
>         Environment: org.apache.aries.transaction.jdbc:2.1.0
> org.apache.aries.transaction.manager:1.1.0
> org.apache.geronimo.components.geronimo-connector:3.1.1
>            Reporter: Aleksey Sushko
>            Priority: Critical
>         Attachments: transaction-itest.zip
>
>
> Tests show incorrect operation of the database.
> Stack error bit different. But the result is the same.
> If the error on the level of queries to the database, the test falls.
> If the error in the logic of business process, the test passes.
> {code}throw new Exception("send error");  // it's test work OK{code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to