Почему setNetworkTimeout вызывает исключение тайм-аута при запросах с функцией?

#java #postgresql #jdbc #timeout #pg-jdbc

#java #postgresql #jdbc #тайм-аут #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:

PostgresSQL передает результирующие строки клиенту, как только они становятся доступными.

В вашем первом запросе первая строка результата будет возвращена довольно скоро, даже если для завершения запроса требуется много времени. Драйвер JDBC собирает результаты и ожидает, пока запрос не будет выполнен, но сетевое соединение не будет простаивать дольше.

Второй запрос занимает примерно столько же времени, сколько и первый, но он не может вернуть свою первую (и единственную) результирующую строку, пока не будут вычислены все результирующие строки из объединения. Таким образом, существует длительное время простоя сетевого соединения, что вызывает тайм-аут.