Fix SQLiteException in resolveRecipient by checking cache before opening connection

resolveRecipient(ServiceId) opens a pooled connection and starts a
BEGIN IMMEDIATE transaction via setAutoCommit(false), then checks
the in-memory cache. On a cache hit, the method returns early via
try-with-resources, closing the connection without committing.

When HikariCP reclaims the connection, it calls setAutoCommit(true)
to reset it. The sqlite-jdbc driver unconditionally executes COMMIT
at this point, but the transaction was already implicitly rolled back
by SQLite when the connection was returned — causing:

  SQLiteException: [SQLITE_ERROR] cannot commit - no transaction is active

This error corrupts the pooled connection state and causes subsequent
operations to fail.

Fix: check the cache before calling getConnection(). On cache hits,
no connection is opened and no transaction is started. On cache misses,
the existing behavior is preserved (open connection, BEGIN IMMEDIATE,
resolve or create recipient, COMMIT).
This commit is contained in:
tonycpsu 2026-04-07 23:07:15 -04:00
parent 763ddf85e6
commit 6c5945310c

View File

@ -184,12 +184,12 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
@Override
public RecipientId resolveRecipient(final ServiceId serviceId) {
final var recipientWithAddress = recipientAddressCache.get(serviceId);
if (recipientWithAddress != null) {
return recipientWithAddress.id();
}
try (final var connection = database.getConnection()) {
connection.setAutoCommit(false);
final var recipientWithAddress = recipientAddressCache.get(serviceId);
if (recipientWithAddress != null) {
return recipientWithAddress.id();
}
final var recipientId = resolveRecipientLocked(connection, serviceId);
connection.commit();
return recipientId;