MySQL KILL QUERY and HikariCP validation: can the pool detect a transaction left by a cancelled statement?
0 reputation · 05 Oct 2020, 15:10 UTC
0 reputation · 05 Oct 2020, 15:10 UTC
When a long‑running DML statement is terminated with KILL QUERY, MySQL aborts the statement but leaves the surrounding transaction open. The storage engine may still be rolling back row changes, which determines when locks are actually released. Meanwhile, a Java connection pool such as HikariCP typically validates a borrowed connection with a lightweight query like SELECT 1. That validation succeeds even if the transaction is still active, so the next borrower can inherit an uncommitted transaction.
The interaction between MySQL’s cancellation primitive and the pool’s validation logic is not fully specified. It is unclear whether KILL QUERY guarantees immediate lock release or whether the pool can reliably detect the intermediate state without additional transaction‑state checks.
KILL QUERY on a DML statement release row locks instantly, or does the engine finish its internal rollback first?35275 reputation · 05 Oct 2020, 21:08 UTC
No, HikariCP's default validation cannot detect a transaction left open by a KILL QUERY. The default validation query (typically SELECT 1) only verifies that the network connection to the database is alive; it does not inspect the session's transactional state. Because KILL QUERY aborts the statement but not the surrounding transaction, the connection remains valid from the pool's perspective, allowing the next borrower to inherit an uncommitted transaction.
The behavior stems from how MySQL and connection pools handle session state:
KILL QUERY, the InnoDB storage engine must roll back any partial changes made by that specific statement. Row locks are not released instantly; they are held until the internal rollback process completes.KILL QUERY is designed to stop the current execution, not to terminate the session or roll back the entire transaction. The transaction remains ACTIVE.connectionTestQuery (or the JDBC 4 isValid() call) simply checks for a successful round-trip. Since the session is still active and capable of executing a simple SELECT, the pool considers the connection healthy.SELECT @@transaction_isolation is often used, a more explicit check involves querying the transaction ID or using a custom function.connectionTestQuery property to your state-aware SQL. If the query fails or returns an unexpected result, HikariCP will evict the connection from the pool.connection.rollback() in a finally block or uses try-with-resources to ensure the connection is returned to the pool in a clean state.To verify this behavior in a staging environment (assuming MySQL 8.0+ and InnoDB):
-- Session 1: Start a transaction and a heavy update
START TRANSACTION;
UPDATE large_table SET status = 'processing' WHERE id < 1000000;
-- Session 2: Kill the query
SHOW PROCESSLIST;
KILL QUERY [thread_id];
-- Session 1: Check transaction status
-- This will still show as active/uncommitted
SELECT @@transaction_isolation;
To determine if a custom validation query is the most efficient path, please confirm if you are using InnoDB or a different storage engine, as rollback timing and lock release semantics vary by engine.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.