我正在尝试将超时添加到jdbc/query
和jdbc/execute!
。在网络上的某个地方,我发现这两个功能都选择了:timeout
。 Documention还说,这些选项被传递到prepare-statment
,后者将:timeout
作为选项。
我的函数调用看起来像,
(jdbc/query db-read-spec query {:timeout 2})
(jdbc/execute! db-write-spec query {:timeout 2})
这是怎么做到的?如果是,我该如何测试?
[如果有其他方法可以测试,也可以使用。
您可以在mysql-select-query上使用query-hint(以毫秒为单位的时间)
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))))
您应该使用非常复杂的查询才能在1ms内使用;
:timeout
选项导致在.setQueryTimeout
罩下使用的PreparedStatement
上调用clojure.java.jdbc
。它以seconds(而不是毫秒)为单位,因此您的查询必须非常慢,超时2,000秒(仅半个多小时)才能生效。
JDBC在其多个类中支持几种不同的超时。例如,javax.sql.DataSource
和.setLoginTimeout
也都支持java.sql.DriverManager
(以秒为单位)。
还有一些特定于数据库的选项,您可以将其添加到连接字符串(可以将其添加为“ db-spec”中的其他键/值对),以控制较低级别的超时。例如,MySQL在连接字符串中支持connectionTimeout
和socketTimeout
,它们都在milliseconds中。 clojure.java.jdbc
允许将这些作为:connectTimeout
和:socketTimeout
键分别提供在您的“ db-spec”哈希图中。
请注意,此时clojure.java.jdbc
被认为是“稳定的”,并且目前和将来的所有开发工作都集中在next.jdbc
上。由于next.jdbc
直接对JDBC对象进行操作,因此更易于使用next.jdbc
,因此,整个(Java)API也可用。它还具有对连接池的内置支持,并且总体上比loginTimeout
更简单,更快。
我想出了一个解决方法来进行测试。由于我使用postgres,因此可以利用clojure.java.jdbc
我的测试看起来像
select pg_sleep(time-in-seconds)