为什么setNetworkTimeout导致带有功能的查询超时异常?

时间:2019-04-12 14:18:02

标签: java postgresql jdbc timeout pg-jdbc

我已连接到PostgreSQL数据库(使用PostgreSQL JDBC驱动程序),并在其上设置了网络超时(使用setNetworkTimeout方法),对此有些奇怪。

当我将连接用于诸如select * from table之类的简单查询时,这会花费很多时间,它可以正常工作(等待查询返回结果)。 但是,当我将连接用于使用函数(例如select max(a) from table)的查询时,该查询也要花费很多时间,由于超时,它将引发异常。

示例代码:

// Queries which takes more than 5 seconds
String bigQuery = "select * from data.bigtable tb1 inner join data.bigtable tb2 on tb1.a like '%a%'";
String bigQueryWithFunction = "select max(tb1.a) from data.bigtable tb1 inner join data.bigtable tb2 on tb1.a like '%a%'";

// Creating a connection with 5 seconds network timeout
Connection con = source.getConnection();
con.setNetworkTimeout(Executors.newSingleThreadExecutor(), 5000);
con.setAutoCommit(false);

Statement st2 = con.createStatement();
st2.execute(bigQueryWithFunction); // This line DOES throws an exception
st2.execute(bigQuery);             // This line DOES NOT throws an exception

(忽略查询的逻辑。)

有人可以向我解释为什么会发生吗?

1 个答案:

答案 0 :(得分:2)

一旦结果行可用,PostgresSQL将结果流发送到客户端。

在您的第一个查询中,即使需要很长时间才能完成查询,第一个结果行也将很快返回。 JDBC驱动程序收集结果并等待直到查询完成,但是网络连接将不再处于空闲状态。

完成第二个查询所需的时间与第一个查询所需的时间相同,但是在计算出联接中的所有结果行之前,它无法返回其第一(也是唯一的)结果行。因此,网络连接上有很长的空闲时间,这会导致超时。