20.03.2021 11:23, Mark Rotteveel wrote:
On 20-03-2021 09:54, Vlad Khorsun wrote:
06.03.2021 20:50, Mark Rotteveel wrote:
Freeing the statement with DSQL_close, DSQL_drop or DSQL_unprepare is deferred (since the v11 protocol). As a result, the free is only sent when something else is subsequently sent over the connection.

   Yes, and usually it is op_commit.

Your assumption about this doesn't always hold. For example, when you use isc_tpb_autocommit and don't use an explicit commit at that point, or when the commit occurs before the statement close, which happens in Jaybird in its default auto-commit mode, and is not unlikely to occur in normal Java code with explicit commits.

For example

// ... obtain connection
connection.setAutoCommit(false);
// ...
try (var preparedStatement pstmt = connection.prepareStatement(
         "update sometable sometable set x = 5 where y = ?")) {
   pstmt.setInt(1, 7);
   pstmt.executeUpdate();
   // commit happens here
   connection.commit();
} // statement close happens here!

  Ok

I wonder if this makes sense for DSQL_drop and DSQL_unprepare, because the end result is that if you free the statement and then leave it alone for a long time, the statement remains prepared and holding existence locks, which can cause issues if you execute DDL dropping or modifying those metadata objects using another connection.

I think that sending the free immediately (at least for DSQL_drop and DSQL_unprepare), and only deferring the processing of the response might make more sense.

What do you think?

   I don't think it makes much sence as there are a lot of other ways to hold 
metadata locks.

The problem I observed is that due to close of the statement you expect the lock to be released, but in fact it is not because the close has not yet been sent to the server. This makes troubleshooting this type of problem harder than necessary. When I stumbled across it two weeks ago when testing Hibernate, I was first hunting for statement leaks in the Java code of both Hibernate and Jaybird.

I have since fixed this in Jaybird's wire protocol implementation (which did a similar thing as fbclient), but the problem remains when using native. In a strange coincidence, yesterday someone reported the exact same problem: https://groups.google.com/g/firebird-java/c/DuIRTYJru7U

  After reading all of this and refreshing my memory I going to agree with you.
Note, immediate send of every op_free_stmt could add performance penalty when
more than one statement is closed\dropped at time. Probably some kind of idle
timer that send deferred packets after short idle timeout could work better.
It looks like Nagle's algorithm, btw.

Regards,
Vlad



Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to