SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: jOOQ 3.21.9 fixes an R2DBC cancellation that could poison a connection for good

· by Serguey Asael Shinder / Serguey Shinder

jOOQ 3.21.9 was published on 25 September, dated 24 September in its notes, together with patch releases for the 3.20 and 3.19 lines. The 3.21.9 release notes list about twenty bug fixes, most of them in the code generator and the parser. Four of them are in jOOQ's R2DBC support, and if you run jOOQ reactively they are the reason to upgrade.

A cancelled query could break its connection permanently (#20203). Cancelling an in-flight R2DBC query orphaned the row subscription and, in the notes' words, permanently poisoned the connection. In a reactive application, cancellation is not an edge case: a client disconnects, a timeout fires, a take(1) stops reading after the first row. A connection that stays unusable after that and goes back to the pool is the kind of fault that shows up later, somewhere else, as a request that hangs for no visible reason.

A transaction could hang when an Error was thrown (#20207). transactionPublisher handled Exception during its initialisation but hung when a java.lang.Error was thrown instead. Related to it, the documentation now says that streaming intermediate results out of a TransactionPublisher is undefined (#20200).

Serguey Asael Shinder: jOOQ 3.21.9 fixes an R2DBC cancellation that could poison a connection for good
jOOQ 3.21.9 fixes an R2DBC cancellation that could poison a connection for good — Serguey Asael Shinder

Batch execution silently skipped context propagation (#20211). R2DBC batches did not propagate the SubscriberProvider context, so whatever you carry in that context - tracing, tenant information - was missing for batched statements without any error.

A rollback failure hid its cause (#20216). When a rollback itself failed, the original reason for rolling back was invisible in the stack trace.

Outside R2DBC, the list includes code generator fixes for Oracle indexes with DESC columns, escaping of UDT and schema names, and Kotlin aliasing constructors, plus a parser that swallowed characters in Oracle-style quoted literals when the delimiter appeared in the string.

What connects the four R2DBC entries is that none of them fails loudly at the point of the mistake. A poisoned connection returns to the pool, a hang is just an absence of progress, missing context leaves a gap in traces, and a hidden rollback cause sends whoever reads the log after the wrong exception. If your application uses jOOQ over R2DBC and you have ever seen an unexplained stall after a client went away, this release is worth taking before you go looking elsewhere.