You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2019/12/20 09:15:54 UTC
[ignite] branch master updated: IGNITE-12462: JDBC thin: Add JDBC
URL properties support for query timeout and for connection timeout. This
closes #7156.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 9f19e01 IGNITE-12462: JDBC thin: Add JDBC URL properties support for query timeout and for connection timeout. This closes #7156.
9f19e01 is described below
commit 9f19e0160b1ca43a27908849ad46c65ebd8689f1
Author: amashenkov <an...@gmail.com>
AuthorDate: Wed Jul 31 20:00:40 2019 +0300
IGNITE-12462: JDBC thin: Add JDBC URL properties support for query timeout and for connection timeout. This closes #7156.
Signed-off-by: Andrey V. Mashenkov <an...@gmail.com>
---
.../thin/JdbcThinConnectionTimeoutSelfTest.java | 96 +++++++++++++++++++---
.../thin/JdbcThinStatementTimeoutSelfTest.java | 62 +++++++++++++-
.../internal/jdbc/thin/ConnectionProperties.java | 28 +++++++
.../jdbc/thin/ConnectionPropertiesImpl.java | 38 ++++++++-
.../internal/jdbc/thin/JdbcThinConnection.java | 7 ++
5 files changed, 215 insertions(+), 16 deletions(-)
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionTimeoutSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionTimeoutSelfTest.java
index 0d77b73..c739afa 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionTimeoutSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionTimeoutSelfTest.java
@@ -144,7 +144,6 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
*/
@Test
public void testSettingNegativeConnectionTimeout() {
-
GridTestUtils.assertThrows(log,
() -> {
conn.setNetworkTimeout(EXECUTOR_STUB, -1);
@@ -154,12 +153,31 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
}
/**
+ *
+ */
+ @Test
+ public void testNegativeConnectionTimeout() {
+ GridTestUtils.assertThrows(log,
+ () -> {
+ try(final Connection conn = DriverManager.getConnection(URL+"?connectionTimeout=-1")) {
+ return null;
+ }
+ },
+ SQLException.class, "Property cannot be lower than 0 [name=connectionTimeout, value=-1]");
+ }
+
+ /**
* @throws Exception If failed.
*/
@Test
public void testConnectionTimeoutRetrieval() throws Exception {
- conn.setNetworkTimeout(EXECUTOR_STUB, 2000);
- assertEquals(2000, conn.getNetworkTimeout());
+ try (final Connection conn = DriverManager.getConnection(URL + "?connectionTimeout=1000")) {
+ assertEquals(1000, conn.getNetworkTimeout());
+
+ conn.setNetworkTimeout(EXECUTOR_STUB, 2000);
+
+ assertEquals(2000, conn.getNetworkTimeout());
+ }
}
/**
@@ -167,7 +185,6 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
*/
@Test
public void testConnectionTimeout() throws Exception {
-
conn.setNetworkTimeout(EXECUTOR_STUB, 1000);
GridTestUtils.assertThrows(log,
@@ -189,13 +206,41 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
* @throws Exception If failed.
*/
@Test
+ public void testUrlConnectionTimeoutProperty() throws Exception {
+ try (final Connection conn = DriverManager.getConnection(URL + "?connectionTimeout=1000")) {
+ conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
+
+ try (final Statement stmt = conn.createStatement()) {
+ GridTestUtils.assertThrows(log,
+ () -> {
+ stmt.execute("select sleep_func(2000)");
+
+ return null;
+ },
+ SQLException.class, "Connection timed out.");
+
+ GridTestUtils.assertThrows(log,
+ () -> {
+ stmt.execute("select 1");
+
+ return null;
+ },
+ SQLException.class, "Statement is closed.");
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ @Test
public void testQueryTimeoutOccursBeforeConnectionTimeout() throws Exception {
conn.setNetworkTimeout(EXECUTOR_STUB, 10_000);
stmt.setQueryTimeout(1);
GridTestUtils.assertThrows(log, () -> {
- stmt.executeQuery("select sleep_func(10) from Integer;");
+ stmt.executeQuery("select sleep_func(3) from Integer;");
return null;
}, SQLTimeoutException.class, "The query was cancelled while executing.");
@@ -207,17 +252,43 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
* @throws Exception If failed.
*/
@Test
- public void testConnectionTimeoutUpdate() throws Exception {
- conn.setNetworkTimeout(EXECUTOR_STUB, 5000);
+ public void testUrlQueryTimeoutProperty() throws Exception {
+ try (final Connection conn = DriverManager.getConnection(URL + "?connectionTimeout=10000&queryTimeout=1")) {
+ conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
- stmt.execute("select sleep_func(1000)");
+ final Statement stmt = conn.createStatement();
- conn.setNetworkTimeout(EXECUTOR_STUB, 500);
+ GridTestUtils.assertThrows(log, () -> {
+ stmt.executeQuery("select sleep_func(3) from Integer;");
+
+ return null;
+ }, SQLTimeoutException.class, "The query was cancelled while executing.");
+
+ stmt.execute("select 1");
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testConnectionTimeoutUpdate() throws Exception {
+ try (final Connection conn = DriverManager.getConnection(URL +
+ "?connectionTimeout=5000")) {
+ conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
+
+ final Statement stmt = conn.createStatement();
- GridTestUtils.assertThrows(log, () -> {
stmt.execute("select sleep_func(1000)");
- return null;
- }, SQLException.class, "Connection timed out.");
+
+ conn.setNetworkTimeout(EXECUTOR_STUB, 500);
+
+ GridTestUtils.assertThrows(log, () -> {
+ stmt.execute("select sleep_func(1000)");
+
+ return null;
+ }, SQLException.class, "Connection timed out.");
+ }
}
/**
@@ -235,6 +306,7 @@ public class JdbcThinConnectionTimeoutSelfTest extends JdbcThinAbstractSelfTest
GridTestUtils.assertThrows(log,
() -> {
stmt.cancel();
+
return null;
},
SQLException.class, "Statement is closed.");
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementTimeoutSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementTimeoutSelfTest.java
index 9d6b742..a7c26cf 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementTimeoutSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementTimeoutSelfTest.java
@@ -147,6 +147,21 @@ public class JdbcThinStatementTimeoutSelfTest extends JdbcThinAbstractSelfTest {
}
/**
+ * Trying to set negative timeout. <code>SQLException</> with message "Invalid timeout value." is expected.
+ * @throws SQLException If failed.
+ */
+ @Test
+ public void testNegativeQueryTimeout() throws SQLException {
+ GridTestUtils.assertThrows(log, () -> {
+ try (final Connection conn = DriverManager.getConnection(URL + "?queryTimeout=-1")) {
+ try (final Statement stmt = conn.createStatement()) {
+ return null;
+ }
+ }
+ }, SQLException.class, "Property cannot be lower than 0 [name=queryTimeout, value=-1]");
+ }
+
+ /**
* Trying to set zero timeout. Zero timeout means no timeout, so no exception is expected.
*
* @throws Exception If failed.
@@ -159,6 +174,22 @@ public class JdbcThinStatementTimeoutSelfTest extends JdbcThinAbstractSelfTest {
}
/**
+ * Trying to set zero timeout. Zero timeout means no timeout, so no exception is expected.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testZeroQueryTimeout() throws Exception {
+ try(final Connection conn = DriverManager.getConnection(URL+"?queryTimeout=0")) {
+ conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
+
+ try (final Statement stmt = conn.createStatement()) {
+ stmt.executeQuery("select sleep_func(1000);");
+ }
+ }
+ }
+
+ /**
* Setting timeout that is greater than query execution time. <code>SQLTimeoutException</code> is expected.
*
* @throws Exception If failed.
@@ -175,6 +206,31 @@ public class JdbcThinStatementTimeoutSelfTest extends JdbcThinAbstractSelfTest {
}
/**
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testQueryTimeoutRetrival() throws Exception {
+ try(final Connection conn = DriverManager.getConnection(URL+"?queryTimeout=5")) {
+ conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
+
+ try (final Statement stmt = conn.createStatement()) {
+ stmt.executeQuery("select sleep_func(2);");
+ }
+
+ try (final Statement stmt = conn.createStatement()) {
+ stmt.setQueryTimeout(1);
+
+ GridTestUtils.assertThrows(log, () -> {
+ // This takes 10_000 ms.
+ stmt.executeQuery("select sleep_func(2) from Integer;");
+
+ return null;
+ }, SQLTimeoutException.class, "The query was cancelled while executing.");
+ }
+ }
+ }
+
+ /**
* Setting timeout that is greater than query execution time. Running same query multiple times.
* <code>SQLTimeoutException</code> is expected in all cases.
*
@@ -186,16 +242,18 @@ public class JdbcThinStatementTimeoutSelfTest extends JdbcThinAbstractSelfTest {
stmt.setQueryTimeout(2);
GridTestUtils.assertThrows(log, () -> {
- stmt.executeQuery("select sleep_func(10) from Integer;");
+ stmt.executeQuery("select sleep_func(5) from Integer;");
return null;
}, SQLTimeoutException.class, "The query was cancelled while executing.");
GridTestUtils.assertThrows(log, () -> {
- stmt.executeQuery("select sleep_func(10) from Integer;");
+ stmt.executeQuery("select sleep_func(5) from Integer;");
return null;
}, SQLTimeoutException.class, "The query was cancelled while executing.");
+
+ stmt.executeQuery("select sleep_func(50)");
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionProperties.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionProperties.java
index 90b21e7..f728d12 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionProperties.java
@@ -459,4 +459,32 @@ public interface ConnectionProperties {
*/
public void setAffinityAwarenessPartitionDistributionsCacheSize(
int affinityAwarenessPartDistributionsCacheSize) throws SQLException;
+
+ /**
+ * Note: zero value means there is no limits.
+ *
+ * @return Query timeout in seconds.
+ */
+ @Nullable public Integer getQueryTimeout();
+
+ /**
+ * Note: zero value means there is no limits.
+ *
+ * @param qryTimeout Query timeout in seconds.
+ */
+ public void setQueryTimeout(@Nullable Integer qryTimeout) throws SQLException;
+
+ /**
+ * Note: zero value means there is no limits.
+ *
+ * @return Connection timeout in milliseconds.
+ */
+ @Nullable public int getConnectionTimeout();
+
+ /**
+ * Note: zero value means there is no limits.
+ *
+ * @param connTimeout Connection timeout in milliseconds.
+ */
+ public void setConnectionTimeout(@Nullable Integer connTimeout) throws SQLException;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionPropertiesImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionPropertiesImpl.java
index 0237941..30af93f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionPropertiesImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/ConnectionPropertiesImpl.java
@@ -212,6 +212,18 @@ public class ConnectionPropertiesImpl implements ConnectionProperties, Serializa
"The size of partition distributions cache that is used within affinity awareness optimization.",
1_000, false, 1, Integer.MAX_VALUE);
+ /** Query timeout. */
+ private IntegerProperty qryTimeout = new IntegerProperty("queryTimeout",
+ "Sets the number of seconds the driver will wait for a <code>Statement</code> object to execute." +
+ " Zero means there is no limits.",
+ 0, false, 0, Integer.MAX_VALUE);
+
+ /** JDBC connection timeout. */
+ private IntegerProperty connTimeout = new IntegerProperty("connectionTimeout",
+ "Sets the number of milliseconds JDBC client will waits for server to response." +
+ " Zero means there is no limits.",
+ 0, false, 0, Integer.MAX_VALUE);
+
/** Properties array. */
private final ConnectionProperty [] propsArray = {
distributedJoins, enforceJoinOrder, collocated, replicatedOnly, autoCloseServerCursor,
@@ -225,7 +237,9 @@ public class ConnectionPropertiesImpl implements ConnectionProperties, Serializa
affinityAwareness,
updateBatchSize,
affinityAwarenessSQLCacheSize,
- affinityAwarenessPartDistributionsCacheSize
+ affinityAwarenessPartDistributionsCacheSize,
+ qryTimeout,
+ connTimeout
};
/** {@inheritDoc} */
@@ -574,6 +588,26 @@ public class ConnectionPropertiesImpl implements ConnectionProperties, Serializa
affinityAwarenessPartDistributionsCacheSize);
}
+ /** {@inheritDoc} */
+ @Override public Integer getQueryTimeout() {
+ return qryTimeout.value();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setQueryTimeout(@Nullable Integer timeout) throws SQLException {
+ qryTimeout.setValue(timeout);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getConnectionTimeout() {
+ return connTimeout.value();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setConnectionTimeout(@Nullable Integer timeout) throws SQLException {
+ connTimeout.setValue(timeout);
+ }
+
/**
* @param url URL connection.
* @param props Environment properties.
@@ -1082,7 +1116,7 @@ public class ConnectionPropertiesImpl implements ConnectionProperties, Serializa
/** {@inheritDoc} */
@Override void init(String str) throws SQLException {
if (str == null)
- val = dfltVal != null ? (int)dfltVal : null;
+ val = dfltVal != null ? (Number)dfltVal : null;
else {
try {
setValue(parse(str));
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
index 3dddb83..60fc1c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
@@ -203,6 +203,9 @@ public class JdbcThinConnection implements Connection {
/** Network timeout. */
private int netTimeout;
+ /** Query timeout. */
+ private int qryTimeout;
+
/** Background periodical maintenance: query timeouts and reconnection handler. */
private final ScheduledExecutorService maintenanceExecutor = Executors.newScheduledThreadPool(2);
@@ -227,6 +230,8 @@ public class JdbcThinConnection implements Connection {
holdability = HOLD_CURSORS_OVER_COMMIT;
autoCommit = true;
txIsolation = Connection.TRANSACTION_NONE;
+ netTimeout = connProps.getConnectionTimeout();
+ qryTimeout = connProps.getQueryTimeout();
schema = JdbcUtils.normalizeSchema(connProps.getSchema());
@@ -344,6 +349,8 @@ public class JdbcThinConnection implements Connection {
JdbcThinStatement stmt = new JdbcThinStatement(this, resSetHoldability, schema);
+ stmt.setQueryTimeout(qryTimeout);
+
synchronized (stmtsMux) {
stmts.add(stmt);
}