针对PGPool II的Java查询导致“未命名的预准备语句不存在”错误

我有一个使用Postgres数据库的Java应用程序,我正在尝试引入PGPool以扩展我的数据库。 我遇到了Postgres抛出以下错误的问题: unnamed prepared statement does not exist 。 在启动Postgres上的日志记录后,我看到我的应用程序执行的每个select语句都发生了以下事情:

 EDTLOG: 00000: duration: 7.585 ms parse : "my select statement here" EDTLOG: 00000: duration: 0.088 ms bind : "my select statement here" EDTLOG: 00000: duration: 79.014 ms execute : "my select statement here" 

但有时候,在解析/绑定/执行步骤之间PGPool会执行一些额外的查询,所以日志看起来像这样:

 EDTLOG: 00000: duration: 7.585 ms parse : "my select statement here" EDTLOG: 00000: duration: 0.088 ms bind : "my select statement here" EDTLOG: 00000: duration: 0.328 ms statement: SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = 'my_table' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog' EDTLOG: 00000: duration: 79.014 ms execute : "my select statement here" EDTERROR: 26000: unnamed prepared statement does not exist EDTLOG: 00000: duration: 0.022 ms parse S_2: ROLLBACK EDTLOG: 00000: duration: 0.005 ms bind S_2: ROLLBACK EDTLOG: 00000: duration: 0.008 ms execute S_2: ROLLBACK 

根据我的理解,因为查询是未命名的,如果在执行未命名查询之前在该数据库会话期间进入另一个查询,它将被Postgres抛弃。 因此,因为PGPool有时会在解析/绑定/执行步骤之间发出这些额外的查询,导致查询被丢弃。

我的第一个想法是,也许我的Java应用程序不需要为每个查询发送parse / bind / execute语句。 但看起来这是自JDBC版本3和Postgres 7.4以来Postgres JDBC驱动程序的默认行为http://jdbc.postgresql.org/documentation/head/server-prepare.html 。 我想我可以尝试完全禁用服务器端预处理语句,但文档没有指定如何做到这一点,我不确定这是我想要做的事情。

我的第二个想法是让PGPool II停止发送那些元数据查询。 由于我只是想使用PGPool作为负载均衡器,我真的不明白为什么它需要知道关于我的表元数据的所有信息。 我在这里跟踪了在PGPool源的is_system_catalog方法中执行这些查询的代码: https : //github.com/iakio/pgpool-II/blob/master/pool_select_walker.c#L256看来PGPool想知道关于我的表关系由于某种原因,不幸的是我没有看到任何方法来禁用该行为。

任何有关如何解决这个问题的见解将不胜感激。

有关我的环境的一些信息:

 JDBC Driver: postgresql-9.1-901.jdbc4.jar Java version "1.6.0_31" Spring 3.1 managed JPA Hibernate 3.5 Postgres 9.1 

更新:我找到了解决问题的方法。 通过在JDBC URL中放置protocolVersion=2 ,它基本上告诉Postgres JDBC驱动程序不要使用服务器端预处理语句。 这允许我的应用程序在我的数据库前使用PGPool II时运行。 我不得不为了使用PGPool而不得不回到JDBC版本2协议这一事实。

我找到了解决这个问题的方法。 通过在JDBC URL中放置protocolVersion = 2,它基本上告诉Postgres JDBC驱动程序不要使用服务器端预处理语句。 这允许我的应用程序在我的数据库前使用PGPool II时运行。 我不得不为了使用PGPool而不得不回到JDBC版本2协议这一事实。

如果你说出准备好的陈述,那该怎么办?

另一个问题出现了:如果你不需要它们,为什么要使用准备好的陈述?

您可以轻松地针对jdbc驱动程序发出“正常”语句…