[
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)