question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Throw exception when Statement#setQueryTimeout is reached when no network is available.

See original GitHub issue

Driver version or jar name

6.2.1.jre8

SQL Server version

SQL Server 2012

Client operating system

CentOS 7

Java/JVM version

java version “1.8.0_91”

Table schema

N/A

Problem description

In our setup, SQL Server will issue TCP keepalives on idle connections to eagerly detect potentially bad connections. Unfortunately this behavior sometimes results in a good connection be flagged as bad if the keepalives do not reach the other host. We’ve seen instances where SQL Server will terminate the connection, but our application hosts think the connections are still good. (Presumably the keepalives are getting dropped.) When we then attempt to use the connection it hangs. SQL Server will silently drop the packets without responding with a TCP reset. Eventually, we reach the TCP packet retransmitted limit (aka tcp_retries2).

Attempting to set the Statement#setQueryTimeout only works if the server responds with data. If the server is not responding, then the timeout is essentially ignored.

Expected behavior and actual behavior

I believe the timeout should trigger the Statement to terminate immediately, preferably with an exception of some kind.

Currently the code will hang until the socket times out via the retransmitted limit being reached.

Repro code

Here is a simple Java class to execute:

  public static void main(String[] args) throws Exception {
    DriverManager.class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

    Connection connection = DriverManager.getConnection("jdbc:sqlserver://localhost;databaseName=mydatabase", "sa", "Password");
    System.out.println("Cause the TCP connection to be terminated from SQL Server side then hit enter.");
    System.in.read();
    Statement statement = connection.createStatement();
    statement.setQueryTimeout(1);

    try {
      statement.execute("WAITFOR DELAY '00:00:3'; SELECT 1");
    } catch (SQLException e) {
      e.printStackTrace();
    }
    System.out.println("Complete");
  }

Here’s how I terminate the TCP connection from the app host. Basically don’t respond to the TCP keepalives:

# Get the port.
ss -tn | grep 1433

# Drop the packets.
sudo iptables -I INPUT 1 -p tcp --dport <paste-port-number-here> -j DROP

# Wait for a bit...
# Remove the iptables rule once the connection is terminated by SQL Server.
sudo iptables -D INPUT 1

To determine when SQL Server terminates the connection, I use this query:

select * from sys.dm_exec_sessions
where host_name = 'localhost'

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:20 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
cheenamalhotracommented, Apr 11, 2018

Hi @dave-r12

I revisited my initial investigation and came up with a solution to pass the statement property instead. PR #674 shall address this issue both from statement & connection levels. You can now avoid setting it globally and use only when needed on a Statement or set it globally to apply on all statements by default.

1reaction
dave-r12commented, Mar 12, 2018

Got it. Hoping to test this tomorrow morning.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Statement.setQueryTimeout does not throw an Exception ...
I'm using JDBC Microsoft SQL SERVER DRIVER and when i set query timeout, the driver return the query results until that moment.
Read more >
Statement.setQueryTimeout doesn't work! - Oracle Communities
network failures, however I noticed that Statement.executeQuery never throws an exception for a time out when the network goes down (which
Read more >
Troubleshoot query time-out errors - SQL Server
The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. System.Data.
Read more >
Thread: Implementing setQueryTimeout()
In essense the requirement is: calling Statement.execute() should either return a result or throw an exception within some relatively short ...
Read more >
Db2 13 - Java - Common IBM Data Server Driver for JDBC and ...
NO (2): The IBM Data Server Driver for JDBC and SQLJ throws an ... setQueryTimeout method is invoked, the query timeout value that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found