{{ message }}
fix(mysql/replay): synthesize OK for unmocked COM_STMT_RESET#4217
Merged
Conversation
ServerPreparedStatement re-execution under Connector/J 8.x calls
ServerPreparedQuery.prepareExecutePacket(), which opportunistically
emits COM_STMT_RESET to clear cursor / long-data state before sending
the next COM_STMT_EXECUTE. The record run is typically single-tenant
and the driver doesn't think a reset is needed, so no recorded mock
exists for that packet. On the second+ replay execution of the same
prepared statement the driver decides a reset IS needed; the replayer
then walked the entire mock pool without finding a match, fell through
the COM_QUERY-only synthetic-OK fallback (match.go:478), and tripped
query.go:136 ("Connection closing due to no matching mock found"),
tearing down the TCP connection.
To the application that surfaces as:
CJCommunicationsException: Communications link failure
SQLSTATE 08S01
Caused by: java.io.IOException: Socket is closed.
HikariCP marks the connection broken; Spring's JpaTransactionManager
then tries to rollback on that already-broken connection and fails
with "Unable to rollback against JDBC Connection" — which is what the
HTTP 500 body shows in the failing replay (the SET autocommit=0/1
lines that appear alongside are just HikariCP opening a fresh
connection to replace the broken one, not the cause).
Fix is local to matchCommand: declare sCOM_STMT_RESET, and after the
existing COM_QUERY graceful-OK block, add a parallel branch that
returns a synthetic mysql.OKPacket for unmocked COM_STMT_RESET. The
packet is stateless from the mock's perspective — the server's reply
is defined to be OK on success and ERR only for an unknown statement
ID — so synthesizing OK is correct protocol behavior and avoids the
connection-close cascade. The statement_id is preserved in the debug
log for traceability.
Repro path (Spring Boot 3.x + Hibernate 6.x + HikariCP + mysql-connector-j 8.2
against TiDB on port 4000):
1. Record a flow that executes the same @query repository method.
2. Replay; first invocation passes, subsequent invocations of the
same prepared statement hit the reset path and fail with 500
"Unable to rollback against JDBC Connection" + agent-log ERROR
"Connection closing due to no matching mock found" with
request_type=COM_STMT_RESET.
Signed-off-by: Yash Khare <khareyash05@gmail.com>
gouravkrosx
approved these changes
May 25, 2026
🚀 Keploy Performance Test ResultsMulti-Run Validation: Tests run 3 times, pipeline fails only if 2+ runs show regression. Thresholds: P50 < 5ms, P90 < 15ms, P99 < 70ms, RPS >= 100 (±1% tolerance), Error Rate < 1% ✅ Result: PASSED - Only 0 out of 3 runs failed (threshold: 2) P50, P90, and P99 percentiles naturally filter out outliers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

ServerPreparedStatement re-execution under Connector/J 8.x calls ServerPreparedQuery.prepareExecutePacket(), which opportunistically emits COM_STMT_RESET to clear cursor / long-data state before sending the next COM_STMT_EXECUTE. The record run is typically single-tenant and the driver doesn't think a reset is needed, so no recorded mock exists for that packet. On the second+ replay execution of the same prepared statement the driver decides a reset IS needed; the replayer then walked the entire mock pool without finding a match, fell through the COM_QUERY-only synthetic-OK fallback (match.go:478), and tripped query.go:136 ("Connection closing due to no matching mock found"), tearing down the TCP connection.
To the application that surfaces as:
CJCommunicationsException: Communications link failure
SQLSTATE 08S01
Caused by: java.io.IOException: Socket is closed.
HikariCP marks the connection broken; Spring's JpaTransactionManager then tries to rollback on that already-broken connection and fails with "Unable to rollback against JDBC Connection" — which is what the HTTP 500 body shows in the failing replay (the SET autocommit=0/1 lines that appear alongside are just HikariCP opening a fresh connection to replace the broken one, not the cause).
Fix is local to matchCommand: declare sCOM_STMT_RESET, and after the existing COM_QUERY graceful-OK block, add a parallel branch that returns a synthetic mysql.OKPacket for unmocked COM_STMT_RESET. The packet is stateless from the mock's perspective — the server's reply is defined to be OK on success and ERR only for an unknown statement ID — so synthesizing OK is correct protocol behavior and avoids the connection-close cascade. The statement_id is preserved in the debug log for traceability.
Repro path (Spring Boot 3.x + Hibernate 6.x + HikariCP + mysql-connector-j 8.2 against TiDB on port 4000):
Describe the changes that are made
Links & References
Closes: #[issue number that will be closed through this PR]
🔗 Related PRs
🐞 Related Issues
📄 Related Documents
What type of PR is this? (check all applicable)
Added e2e test pipeline?
Added comments for hard-to-understand areas?
Added to documentation?
Are there any sample code or steps to test the changes?
Self Review done?
Any relevant screenshots, recordings or logs?
🧠 Semantics for PR Title & Branch Name
Please ensure your PR title and branch name follow the Keploy semantics:
📌 PR Semantics Guide
📌 Branch Semantics Guide
Examples:
fix: patch MongoDB document update bugfeat/#1-login-flow(You may skip mentioning the issue number in the branch name if the change is small and the PR description clearly explains it.)Additional checklist: