使用HikariCP与pgjdbc-ng驱动的Spring Boot应用连接pgbouncer报错咨询
报错原因
该错误是pgbouncer事务池化模式和pgjdbc-ng驱动默认开启的服务端预处理语句缓存特性冲突导致的:
- 默认情况下pgbouncer工作在事务池模式,同一个物理数据库连接会被分配给多个不同的应用会话复用,物理连接本身不会随应用会话释放而重置
- impossibl/pgjdbc-ng驱动默认会启用服务端预处理语句,会生成固定命名的预处理语句(比如报错中的
TB)存储在PostgreSQL服务端,生命周期和物理连接绑定 - 直连原生PostgreSQL时,应用会话独占物理连接,预处理语句的生命周期和会话完全匹配,不会出现冲突;当接入pgbouncer后,应用会话释放的物理连接会被分给其他会话使用,新会话尝试创建同名预处理语句时就会触发"already exists"报错
解决方案
无需更换HikariCP连接池,只需在JDBC URL中添加以下两个驱动参数即可解决问题:
jdbc:pgsql://[你的pgbouncer地址]:[端口]/[数据库名]?prepareThreshold=-1&statementCacheSize=0
参数说明:
prepareThreshold=-1:禁用服务端预处理语句,所有预处理操作都在客户端完成,不会在PostgreSQL服务端生成命名的预处理语句statementCacheSize=0:关闭驱动层面的预处理语句缓存,避免复用缓存的历史命名预处理语句
内容的提问来源于stack exchange,提问作者priderider
相关产品推荐
相关产品推荐

