Nous avons identifié la cause de ce problème. Cela s'explique par l'implémentation boguée de setQueryTimeout() dans les derniers pilotes JDBC 9.2-100x. Cela peut ne pas se produire si vous ouvrez/fermez la connexion manuellement, mais cela se produit très souvent avec le regroupement de connexions en place et la validation automatique défini sur faux . Dans ce cas, setQueryTimeout() doit être appelé avec une valeur non nulle (par exemple, en utilisant l'annotation Spring framework @Transactional( timeout =xxx )).
Il s'avère que chaque fois qu'une exception SQL est déclenchée lors de l'exécution de l'instruction, le temporisateur d'annulation n'a pas été annulé et reste actif (c'est ainsi qu'il est implémenté). En raison du regroupement, la connexion derrière n'est pas fermée mais est renvoyée au pool. Plus tard, lorsque le minuteur d'annulation se déclenche, il annule de manière aléatoire la requête actuellement associée à la connexion avec laquelle ce minuteur a été créé. En ce moment, c'est une requête totalement différente qui explique l'effet aléatoire.
La solution de contournement suggérée consiste à abandonner setQueryTimeout() et à utiliser la configuration PostgreSQL à la place (statement_timeout). Il ne fournit pas le même niveau de flexibilité mais au moins fonctionne toujours.