title: Use Prepared Statements Correctly with Pooling
impact: HIGH
impactDescription: Avoid prepared statement conflicts in pooled environments
tags: prepared-statements, connection-pooling, transaction-mode
在连接池中正确使用预处理语句
预处理语句与单个数据库连接绑定。在事务模式连接池中,连接被共享,会导致冲突。
错误做法(事务模式池中使用命名预处理语句):
-- 命名预处理语句prepareget_userasselect*fromuserswhereid=$1;-- 在事务模式连接池中,下一个请求可能获得不同的连接executeget_user(123);-- 错误:预处理语句 "get_user" 不存在正确做法(使用匿名语句或会话模式):
-- 方案 1:使用匿名预处理语句(大多数 ORM 会自动这样做)-- 查询在单个协议消息中完成预处理并执行-- 方案 2:在事务模式中使用后立即释放prepareget_userasselect*fromuserswhereid=$1;executeget_user(123);deallocateget_user;-- 方案 3:使用会话模式连接池(端口 5432 对比 6543)-- 连接在整个会话期间保持,预处理语句得以持久检查你的驱动设置:
-- 许多驱动默认使用预处理语句-- Node.js pg:设置 { prepare: false } 以禁用-- JDBC:设置 prepareThreshold=0 以禁用参考:连接池模式下的预处理语句