[
http://issues.apache.org/jira/browse/DERBY-2195?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12461849
]
Yip Ng commented on DERBY-2195:
-------------------------------
Hi Bryan. Indeed, I have the same question too when I was fixing this jira.
At first glance, it appears that it makes sense to call statement context clean
up code when an exception has occurred in the class that creates the new
statement context. However, this does not work well when Server side JDBC
comes into play. The cleanup mechanism for invoking a Java procedure has a
different cleanup code path that uses the global context stack and will clean
up the various contexts in the order that they were pushed down till the "last
context handler". I think the "last context handler" concept is for handling
in the case where the system does not want to rollback the entire execution
context but to a certain statement context. (e.g.: CALL statement may be
executing various SQL statements and each of those statement has its own
statement context. If one SQL statement fails with exception and the Java
procedure decides to handle the exception, it must not rollback the entire
execution context but only up to the statement context object that fails, and
then the Java procedure continues on.)
So if a statement context cleanupOnError() is called within the place where it
pushes it, the sc will be cleaned and removed from the global stack and the
exception is rethrown to the next exception handler which will eventually
invoke ContextManager's cleanupOnError method and cleans up on the current
global context stack. So a statement context here is cleaned up too soon and
if for some reason, the outermost statement (CALL statement) needs to access
its statement context (i.e.: sc.clearSavePoint()), it will throw an internal
exception since the outermost statement context has been popped off. (see
GenericStatementContext's pleaseBeOnStack()).
Hence, I think that that is why the SPS (GenericPreparedStatement) does not
clean up the statement context on error but rely on other classes or mechanisms
such as GenericTriggerExecutor or ContextManager's cleanupOnError() for proper
cleanup.
> Nested triggers not working properly after maximum trigger count exception is
> thrown
> ------------------------------------------------------------------------------------
>
> Key: DERBY-2195
> URL: http://issues.apache.org/jira/browse/DERBY-2195
> Project: Derby
> Issue Type: Bug
> Components: SQL
> Affects Versions: 10.1.3.1, 10.2.1.6, 10.3.0.0
> Environment: Any
> Reporter: Yip Ng
> Assigned To: Yip Ng
> Attachments: derby2195-trunk-diff01.txt, derby2195-trunk-stat01.txt
>
>
> After the maximum allowed nested trigger exception is thrown, subsequent
> statement that result in nested trigger execution may result in the same
> error again even though it does not exceed the limit of nested triggers(16).
> e.g.:
> C:\derby\trunk>java -classpath classes;. org.apache.derby.tools.ij
> ij version 10.3
> ij> connect 'jdbc:derby:wombat;create=true';
> ij> create table t1 (i int);
> 0 rows inserted/updated/deleted
> ij> insert into t1 values 1,2,3;
> 3 rows inserted/updated/deleted
> ij> create trigger tr1 after update on t1 for each row update t1 set i=i+1;
> 0 rows inserted/updated/deleted
> -- force the "maximum depth of nested triggers" error to occur
> ij> update t1 set i=i+1;
> ERROR 54038: Maximum depth of nested triggers was exceeded.
> ij> drop trigger tr1;
> 0 rows inserted/updated/deleted
> ij> create trigger tr1 after update on t1 referencing old as oldt for each
> row update t1 set i=i+1 where oldt.i=2;
> 0 rows inserted/updated/deleted
> -- this should have executed successfully instead of throwing the same error
> again!
> ij> update t1 set i=i+1;
> ERROR 54038: Maximum depth of nested triggers was exceeded.
> ij> disconnect;
> ij> connect 'jdbc:derby:wombat';
> ij> select * from t1;
> I
> -----------
> 1
> 2
> 3
> 3 rows selected
> -- ok after reconnection, it looks like the trigger execution context(TEC)
> may not have been cleanup properly in the previous connection
> ij> update t1 set i=i+1;
> 3 rows inserted/updated/deleted
> ij> select * from t1;
> I
> -----------
> 4
> 5
> 6
> 3 rows selected
> ij>
--
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