db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kristian Waagan (JIRA)" <j...@apache.org>
Subject [jira] Commented: (DERBY-4343) ASSERT FAILED calling setTransactionIsolation checking isolation_ == level on pooled connection
Date Fri, 07 Aug 2009 09:03:14 GMT

    [ https://issues.apache.org/jira/browse/DERBY-4343?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12740453#action_12740453

Kristian Waagan commented on DERBY-4343:

I believe I understand why the assert happens.
When obtaining the pooled connection for the third time, the variable isolation_ is reset
by the following code in Connection.completeReset:
        if (closeStatementsOnClose) {
            // NOTE: This is to match previous behavior.
            //       Investigate and check if it is really necessary.
            this.isolation_ = TRANSACTION_UNKNOWN;
            java.util.Set keySet = openStatements_.keySet();
            for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
                Object o = i.next();
                ((Statement) o).reset(closeStatementsOnClose);
        } else {

When setTransactionIsolation is called, and actually executed, the server doesn't send any
piggybacked update because the level hasn't changed. This means the isolation_ will remain
as UNKNOWN until getTransactionIsolation is called or a different statement causing a change
of the isolation level is executed.

DERBY-4314 causes the assert to never be reached by (in this case) querying the server about
the isolation level and then short-circuiting setTransactionIsolation:
+        // Derby-4314 fix, the client driver should acted like embedded
+        if (level == getTransactionIsolationX())
+            return;

For completeness, removing the return in this case would also make the assert pass, since
getTransactionIsolationX would have updated the value of isolation_.

My take on this assert is that it is doesn't have any consequences "in the real world". Next
time the user asks for the isolation level, it will be fetched from the server and a correct
value will be returned.

I'm +1 for patch DERBY-4314-5.diff, but I'm not yet confident resetting the value to READ_COMMITTED
is the best solution (as of today, I think it is a correct change though).
The patch won't improve the performance, it will just move the round-trip. In some cases I
believe it will make it worse for the initial setTransactionIsolation call, depending on whether
the value being set is READ_COMMITTED or not. If it is, we still get one round-trip (check
+ short-circuit), but if it isn't we get two (check + change).
Note that the situation is slightly different when the client side JDBC statement cache is

This means that for better performance, we need additional changes.
Not thinking ahead, the simplest change would be to assume that the default isolation level
will be READ_COMMITTED for ever. If this turns out to be false in the future, we may get out
of it using version checks.
A better, but more demanding solution, would be to obtain the default isolation level at initial
connection time, for instance using the existing piggybacking feature. This still requires
a version check in the server, but gives us more flexibility [1].
On top of this we have the XA scenario, which I understand requires some extra care to avoid
returning stale/incorrect values.


[1] I'm thinking about optimizing this situation in Connection.completeReset:
       } else {
            // Must reset transaction isolation level if it has been changed.
            if (isolation_ != Connection.TRANSACTION_READ_COMMITTED) {
                // This might not fare well with connection pools, if it has
                // been configured to deliver connection with a different
                // isolation level, i.e. it has to set the isolation level again
                // when it returns connection to client.
                // TODO: Investigate optimization options.
    With the described approach, the default level could be configured in the connection url
with an attribute. I do not know if this is allowed by the relevant standards, or if it is
something we ever want to do.

> ASSERT FAILED calling setTransactionIsolation checking isolation_ == level   on  pooled
> --------------------------------------------------------------------------------------------------
>                 Key: DERBY-4343
>                 URL: https://issues.apache.org/jira/browse/DERBY-4343
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions:
>            Reporter: Kathey Marsden
>         Attachments: TestConnReuse.java
> For DERBY-4314, I thought I would do a little testing to understand the server round
trips in various scenarios for pooled connections.  So I wrote the small attached program
ConnReuse.java and hit this assertion in client:
> Exception in thread "main" org.apache.derby.shared.common.sanity.AssertFailure: ASSERT
>         at org.apache.derby.shared.common.sanity.SanityManager.ASSERT(SanityManager.java:98)
>         at org.apache.derby.client.am.Connection.setTransactionIsolationX(Connection.java:987)
>         at org.apache.derby.client.am.Connection.setTransactionIsolation(Connection.java:915)
>         at org.apache.derby.client.am.LogicalConnection.setTransactionIsolation(LogicalConnection.java:253)
>         at TestConnReuse.main(TestConnReuse.java:32)
> ---------------
> To run the program on trunk:
> java org.apache.derby.drda.NetworkServerControl start
> java TestConnReuse.
> This needs more investigation, but I thought I would go ahead and log the bug.  I tried
this only on  trunk.  I  have not yet
> - Tried it on the branches.
> - Tried it with Lily's DERBY-4314 patch.
> - Tried it with embedded.
> - Tried actually doing something with the prior logical connection which might be related.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message