Hemos descubierto la causa de este problema. Se explica por la implementación defectuosa de setQueryTimeout() en los últimos controladores JDBC 9.2-100x. Es posible que no suceda si abre/cierra la conexión manualmente, pero muy a menudo sucede con la agrupación de conexiones en su lugar y confirmación automática establecido en falso . En este caso, se debe llamar a setQueryTimeout() con un valor distinto de cero (como ejemplo, usando la anotación Spring Framework @Transactional( timeout =xxx )).
Resulta que, cada vez que se genera una excepción de SQL durante la ejecución de la instrucción, el temporizador de cancelación no se cancela y permanece vivo (así es como se implementa). Debido a la agrupación, la conexión posterior no se cierra, sino que se devuelve al grupo. Más tarde, cuando se activa el temporizador de cancelación, cancela aleatoriamente la consulta actualmente asociada con la conexión con la que se creó este temporizador. En este momento, es una consulta totalmente diferente la que explica el efecto de aleatoriedad.
La solución sugerida es renunciar a setQueryTimeout() y usar la configuración de PostgreSQL en su lugar (statement_timeout). No proporciona el mismo nivel de flexibilidad, pero al menos siempre funciona.