[ 
https://issues.apache.org/jira/browse/DERBY-3304?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12557476#action_12557476
 ] 

Dag H. Wanvik commented on DERBY-3304:
--------------------------------------

My preliminary analysis shows that the added code in svn 606106 does
indeed make the difference, but I am not convinced all is kosher, see
below.

When the stored procedure (f2) commits, it leads to a call of
GenericLanguageConnectionContext#resetActivations, which in turn leads
to a call to CallStatementResultSet#close. At this point the dynamic
result set has not yet been constructed.

Here is the call stack (line numbers correspond to svn 606106).
Interestingly, CallStatementResultSet#close is called as part of
CallStatementResultSet#open... Is this correct?

   
org.apache.derby.impl.sql.execute.NoRowsResultSetImpl.close(NoRowsResultSetImpl.java:393)
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.close(CallStatementResultSet.java:108)
   
org.apache.derby.impl.sql.execute.BaseActivation.reset(BaseActivation.java:312)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.resetActivations(GenericLanguageConnectionContext.java:2764)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.doCommit(GenericLanguageConnectionContext.java:1113)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.userCommit(GenericLanguageConnectionContext.java:991)
   
org.apache.derby.impl.jdbc.TransactionResourceImpl.commit(TransactionResourceImpl.java:237)
   org.apache.derby.impl.jdbc.EmbedConnection.commit(EmbedConnection.java:1202)
   commitInProc.Main.f2(Main.java:95)
   org.apache.derby.exe.ac601a400fx0117x605dx1c0ex0000003d76c00.g0
   sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java)
   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   java.lang.reflect.Method.invoke(Method.java:597)
   
org.apache.derby.impl.services.reflect.ReflectMethod.invoke(ReflectMethod.java:46)
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.open(CallStatementResultSet.java:74)
   
org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:370)
   
org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1234)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:624)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:556)
   commitInProc.Main.doSingleDriver(Main.java:58)
   commitInProc.Main.main(Main.java:83)


Now, this close leads to *another* recursive call to
CallStatementResultSet.close, but this time isOpen is false, so
NoRowsResultSetImpl.close returns immediately. At this point we have
CallStatementResultSet#open, #close and #close(frame 2!) on the stack.
   
   
org.apache.derby.impl.sql.execute.NoRowsResultSetImpl.close(NoRowsResultSetImpl.java:334)
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.close(CallStatementResultSet.java:108)
   
org.apache.derby.impl.sql.execute.BaseActivation.reset(BaseActivation.java:312)
   
org.apache.derby.impl.sql.execute.BaseActivation.close(BaseActivation.java:346)
   
org.apache.derby.impl.sql.execute.NoRowsResultSetImpl.close(NoRowsResultSetImpl.java:396)
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.close(CallStatementResultSet.java:108)
   
org.apache.derby.impl.sql.execute.BaseActivation.reset(BaseActivation.java:312)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.resetActivations(GenericLanguageConnectionContext.java:2764)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.doCommit(GenericLanguageConnectionContext.java:1113)
   
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.userCommit(GenericLanguageConnectionContext.java:991)
   
org.apache.derby.impl.jdbc.TransactionResourceImpl.commit(TransactionResourceImpl.java:237)
   org.apache.derby.impl.jdbc.EmbedConnection.commit(EmbedConnection.java:1202)
   commitInProc.Main.f2(Main.java:95)
   org.apache.derby.exe.ac601a400fx0117x605dx1c0ex0000003d76c00.g0
   sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java)
   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   java.lang.reflect.Method.invoke(Method.java:597)
   
org.apache.derby.impl.services.reflect.ReflectMethod.invoke(ReflectMethod.java:46)
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.open(CallStatementResultSet.java:74)
   
org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:370)
   
org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1234)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:624)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:556)
   commitInProc.Main.doSingleDriver(Main.java:58)
    commitInProc.Main.main(Main.java:83)

No dynamic result set is closed here since none has yet been
constructed. Anyway, next, as part of the commit call chain, the
activation of the call statement is also closed.

Now, *before* svn 606106, the activation for the call statement is
closed later; as shown here (numbers correspond to svn 606105):
       
   
org.apache.derby.impl.sql.execute.CallStatementResultSet.close(CallStatementResultSet.java:149)
   
org.apache.derby.impl.sql.execute.BaseActivation.reset(BaseActivation.java:312)
   
org.apache.derby.impl.sql.execute.BaseActivation.close(BaseActivation.java:346)
   
org.apache.derby.impl.sql.GenericActivationHolder.close(GenericActivationHolder.java:463)
   
org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:397)
   
org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1234)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:624)
   org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:556)
   commitInProc.Main.doSingleDriver(Main.java:58)
   commitInProc.Main.main(Main.java:83)

At line 149 of CallStatementResultSet, the dynamic result set is
closed and is thus unavailable. 

But after *606106*, the activation has already been closed *before*
the dynamic result set is assigned, so the dynamic result set is not
closed as part of closing the activation when the call to f2 finishes
and is thus available!

Not sure what to make of all this, but it seems weird that the commit
should close the CallStatementResultSet when is in the process of
being opened. Also, the fact that the commit closes the activation of
the call statement looks wrong(?).


> Explicit commit inside a java procedure makes a dynamic result sets passed 
> out unavailable
> ------------------------------------------------------------------------------------------
>
>                 Key: DERBY-3304
>                 URL: https://issues.apache.org/jira/browse/DERBY-3304
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.4.0.0
>            Reporter: Daniel John Debrunner
>         Attachments: Main.java
>
>
> Repro (Main.java) that shows changed behavior after svn 602991
> (the patch committed for this issue). It seems a regression: (originally from 
> Dag H. Wanvik attached to DERBY-1585)
> An explicit commit inside a stored procedure makes a dynamic result sets 
> passed out unavailable, even if the commit is executed *prior* to the result 
> set; as in the repro.

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

Reply via email to