[
http://issues.apache.org/jira/browse/DERBY-1108?page=comments#action_12416823 ]
A B commented on DERBY-1108:
----------------------------
I'm not very well acquainted with this code, but based on the example of
"escape analysis" posted by the JVM team, I think I understand why this test is
failing with IBM 1.5.
If we look at the test program again, we can see that it very closely mimics
the example of "escape analysis" offered by the JVM team. In particular:
System.out.println("done creating table and inserting data.");
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
ResultSet rs = stmt.executeQuery("select * from T1");
==> Under Java 5.0 rs is eligible for GC here...
System.out.println("current isolation level: " +
getIsoLevelName(conn.getTransactionIsolation()));
conn.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
System.out.println("current isolation level: " +
getIsoLevelName(conn.getTransactionIsolation()));
==> Under previous versions, rs is eligible for GC here...
So with ibm15, rs becomes eligible for GC _prior_ to the call to
setTransactionIsolation because it (rs) is no longer referenced after it is
created. Then the call to gc() in verifyAllHeldResultSetsAreClosed() does the
escape analysis, sees that rs is now eligible for GC and so collects it. As
part of that collection process the JVM calls "finalize()", which takes us to
EmbedResultSet.finalize(), and there we see this:
/**
JDBC states that a ResultSet is closed when garbage collected.
We simply mark the activation as unused. Some later use
of the connection will clean everything up.
@exception Throwable Allows any exception to be thrown during
finalize
*/
protected void finalize() throws Throwable {
super.finalize();
if (finalizeActivation != null) {
finalizeActivation.markUnused();
}
}
Thus finalizeActiviation is now marked as "unused", which means we end up
ignoring the activation in the verifyAllHeldResultSetsAreClosed() method:
if (!a.isInUse())
{
continue;
}
And therefore we return "true" from the method and no error is thrown.
To prove this, I added a very simple (albeit meaningless) reference to "rs"
after the call to setTransactionIsolation:
System.out.println("done creating table and inserting data.");
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
ResultSet rs = stmt.executeQuery("select * from T1");
System.out.println("current isolation level: " +
getIsoLevelName(conn.getTransactionIsolation()));
conn.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
System.out.println("current isolation level: " +
getIsoLevelName(conn.getTransactionIsolation()));
System.out.println(rs); // <== Added by Army
With this simple line, the escape analysis will *not* mark rs eligible for GC
prior to setTransactionIsolation, which means we won't call "finalize()", which
means the activation will remain "in use", and therefore we'll get the
exception.
All of that said, I added System.outs to the test program to see what the
object id of "rs" is before the call to setTransactionIsolation, and I also
added System.outs to see what the object id of the "rs" is inside
verifyAllHeldResultSetsAreClosed(). Not surprisingly, the objects are NOT the
same. In the test program we see:
[EMAIL PROTECTED]
but in verifyAllHeldResultSetsAreClosed() we see:
[EMAIL PROTECTED]
So as far as I can tell, the test program no longer references the
EmbedResultSet, so it's marked as "eligible for GC" and is garbage collected by
escape analysis; however, that EmbedResultSet was in turn referencing another
object--BulkTableScanResultSet--that *is* still referenced (by the activation),
and that's the result set that should have caused the error--but since we
"bailed" on the error checking because the activiation was no longer "in use",
we never checked the underlying result set and therefore we didn't throw the
exception.
That's my take on it after looking at it briefly. I still don't know for sure
who's "at fault" here (the JVM or Derby)--I'd have to look at it more to say
one way or the other. But that's my first take on the issue...
Comments/input/feedback are, as always, much appreciated...
Army
> The test jdbcapi/setTransactionIsolation.java fails with ibm jvm1.5
> -------------------------------------------------------------------
>
> Key: DERBY-1108
> URL: http://issues.apache.org/jira/browse/DERBY-1108
> Project: Derby
> Type: Bug
> Components: Regression Test Failure
> Versions: 10.2.0.0
> Environment: java version "1.5.0"
> Java(TM) 2 Runtime Environment, Standard Edition (build pwi32dev-20051104)
> IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32
> j9vmwi3223-2005110
> 3 (JIT enabled)
> J9VM - 20051027_03723_lHdSMR
> JIT - 20051027_1437_r8
> GC - 20051020_AA)
> JCL - 20051102
> Reporter: Manjula Kutty
> Attachments: test.java
>
> The test jdbcapi/setTransactionIsolation.java fails with ibmjvm15. I think
> the cause of this failure is , the jvm is not throwing an exception while
> trying to change the transaction isolation when there is holdable cursor on
> a resultset. Other jvms like sun jdk1.5, ibm142 throws the expected
> exception. while ibm15 does allow to change the transaction isolation when
> there is a hold cursor on a result set.
> Already reported this issue with the ibmjvm people and they are looking in to
> it
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira