MySQL: restore blocked column to BOOLEAN so IX_TXNO_OUTBOX_1 is usable - #1070
Open
andreib-goji wants to merge 1 commit into
Open
andreib-goji wants to merge 1 commit into
andreib-goji wants to merge 1 commit into
Conversation
badgerwithagun
requested changes
Jul 19, 2026
badgerwithagun
left a comment
Member
There was a problem hiding this comment.
Hi @andreib-goji and thank you for your PR.
Looking at migration 6, I actually think this was an error in the PR that introduced the schema change. blocked shouldn't be a varchar. The correct change here will be to add a migration to return the column to the correct type (correctly migrating existing values) rather than work around it.
We also need an acceptance test (in https://github.com/gruelbox/transaction-outbox/blob/master/transactionoutbox-testing/src/main/java/com/gruelbox/transactionoutbox/testing/AbstractAcceptanceTest.java) to ensure the original issue is resolved on all dialects. You need to replicate the failed blocking symptoms there before applying your fix.
Migration 6 renamed blacklisted to blocked but also changed the MySQL column type from BOOLEAN to VARCHAR(250). Comparing a VARCHAR against a boolean needs an implicit cast, so the retention cleanup DELETE cannot use blocked as an index range condition on IX_TXNO_OUTBOX_1 and scans the whole processed = true region. Under REPEATABLE READ it next-key-locks every retained row it scans - even when it deletes nothing - and concurrent outbox writers hit lock wait timeouts. Migration 14 converts the column back to BOOLEAN; existing "0"/"1" values convert in place. Covered by dialect SQL tests, a conversion test that migrates a populated v13 schema, and an acceptance test proving an idle cleanup transaction no longer blocks writes to retained rows.
andreib-goji
force-pushed
the
fix-mysql-boolean-literals
branch
from
July 24, 2026 08:25
19a915e to
2504122
Compare
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem: migration 6 renamed blacklisted to blocked but also changed the MySQL column type from
BOOLEANtoVARCHAR(250). Boolean comparisons against theVARCHARneed an implicit cast, so the retention cleanupDELETEcan't use blocked as an index range condition onIX_TXNO_OUTBOX_1and scans the wholeprocessed = trueregion. UnderREPEATABLE READitnext-key-locksevery retained row it scans (even when it deletes nothin) and concurrent outbox writers hit lock wait timeouts.Fix: migration 14 (MySQL dialects only) converts the column back to
BOOLEAN. Existing "0"/"1" values convert in place. Queries keep boolean literals.Tests:
TestMySqlDialectpins migration 14 SQL and boolean comparisons.migration14ConvertsExistingBlockedValuesrebuilds a populated v13 schema by replaying real migrations, then migrates and verifies type and semantics (MySQL 5 + 8).retentionCleanupDoesNotLockRetainedRecordsproves an idle cleanup transaction no longer blocks writes to retained rows. Passes on H2, MySQL 5/8, PostgreSQL 16, Oracle 21, SQL Server 2019.