aries-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Aleksey Sushko (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (ARIES-1279) Transaction does not work on error SQLException
Date Fri, 12 Dec 2014 07:24:13 GMT

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

Aleksey Sushko edited comment on ARIES-1279 at 12/12/14 7:23 AM:
-----------------------------------------------------------------

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.

There is another 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.



was (Author: alexey-s):
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)

Mime
View raw message