Java / JDB c Тайм-аут в ближайшем будущем - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь добавить время ожидания к jdbc/query и jdbc/execute!. Где-то в сети я обнаружил, что обе функции принимают :timeout в качестве опции. В документации также сказано, что опции передаются в prepare-statment, который принимает в качестве опции :timeout.

Мои вызовы функций выглядят так:

(jdbc/query db-read-spec query {:timeout 2})

(jdbc/execute! db-write-spec query {:timeout 2})

Это так? Если да, как мне проверить это?

Если есть другой способ сделать это, который можно проверить, это тоже работает.

Ответы [ 3 ]

0 голосов
/ 26 марта 2020

Опция :timeout вызывает .setQueryTimeout для вызова PreparedStatement, используемого под колпаком clojure.java.jdbc. Он находится в секундах , а не в миллисекундах, поэтому ваш запрос должен быть очень медленным в течение 2000 секунд (чуть более получаса), чтобы его действие вступило в силу.

JDB C поддерживает несколько разных таймаутов в нескольких классах. Например, javax.sql.DataSource поддерживает .setLoginTimeout (также в секундах), как и java.sql.DriverManager.

Существуют также параметры базы данных c, которые можно добавить в строку подключения (которую можно добавить как дополнительные пары ключ / значение в вашей «db-spe c») для контроля таймаутов нижнего уровня. Например, MySQL поддерживает connectionTimeout и socketTimeout в строке подключения - и оба они находятся в миллисекундах . clojure.java.jdbc позволяет указывать их на вашей карте "db-spe c" ha sh как :connectTimeout и :socketTimeout соответственно.

Обратите внимание, что clojure.java.jdbc считается "стабильным" «на данный момент и все текущие и будущие усилия по разработке сосредоточены на next.jdbc на данный момент. next.jdbc упрощает использование loginTimeout, поскольку он работает непосредственно с объектами JDB C, поэтому доступен весь (Java) API. Он также имеет встроенную поддержку для пулов соединений и в целом проще и быстрее, чем clojure.java.jdbc.

0 голосов
/ 29 марта 2020

Я придумаю, как это проверить. Поскольку я использую postgres, я могу использовать select pg_sleep(time-in-seconds)

И мой тест выглядит как

(is (thrown-with-msg? PSQLException #"ERROR: canceling statement due to user request"
                          (fetch-or-save "select pg_sleep(3)")))
0 голосов
/ 26 марта 2020

Вы можете использовать query-hint на mysql -select-query (время в мс)

SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM t1 INNER JOIN t2 WHERE....

, тогда вы можете просто обернуть свои запросы :

(defn timed-query [db query t]
  (j/query db [(str (subs query 0 6)
                    (format " /*+ MAX_EXECUTION_TIME(%s) */ " t)
                    (subs query 7))]))

и проверка:

(deftest test-query-timeout
  (is (thrown? Exception (timed-query db "select * from Employees where id>5" 1))))

, для этого вам нужно использовать очень сложные запросы для работы с 1 мс;

...