-
Notifications
You must be signed in to change notification settings - Fork 426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Throw exception when Statement#setQueryTimeout is reached when no network is available. #525
Comments
Hi @dave-r12 . I tried running the commands you mentioned on the same client machine, and my application does not hang and I am still getting the query timeout. If I understand correctly, you are getting the socket timeout exception rather than the query timeout? |
Yes that's right. Doesn't the query timeout rely on receiving a packet back from the server? In this case, the server is unreachable so it never sends anything back.
Umm, not sure if they are default. Looks like it's set to 30 seconds. I don't see any option for interval. |
@v-afrafi any luck? |
Hi @dave-r12 . Apologies for responding late. I also got the socket timeout exception. Will be investigating this and will get back to you shortly. Thanks! |
Hi @dave-r12. looking at this issue, I see that the driver is sending the attention packet to cancel the query, however, as you mentioned since it can't figure out that the connection is silently dropped, it gets stuck at that point until we get the connection timeout. I am trying to push a fix, will update you here once done. It also seems like that postgreSql also has a connection property for this. |
@v-afrafi cool, thanks for tracking this down. |
Hey @v-afrafi sorry not yet. I'll try to take a look by end of week. |
Got it. Hoping to test this tomorrow morning. |
Alright, so I'm trying to test this. I checked out a version of that PR and built it locally and then ran my test program. I'm still seeing the connection hang even after setting the cancel query timeout. I'll continue investigating to make sure my setup is right. Here is the connection string I'm using:
|
So it seems this also requires setting the queryTimeout parameter? We had been setting this on the statement.setQueryTimeout(1); Any way to avoid setting it globally? |
I can confirm that setting both the queryTimeout and cancelQueryTimeout, it now throws an exception:
For our use case, we want to use this to detect connections that have gone bad in a connection pool. I'm thinking when we borrow a connection from the pool we'd do this check first. I'm unsure what the consequences would be if we set these parameters globally. Ideally we'd only want this when setting the |
Hi @dave-r12 These 2 properties
So, in case you want to fetch a connection from connection pool, the connection properties must be identified and reset if needed, before executing query to detect bad connections. |
Hi @dave-r12 Do you have any questions before we decide to merge the PR? |
Hey, alright. I guess I'm not completely understanding the comment about |
Hi @dave-r12 I revisited my initial investigation and came up with a solution to pass the statement property instead. |
@cheenamalhotra awesome! |
…ut connection property | GitHub issue microsoft#525
Closing the issue since PR #674 got merged to dev. |
…alue even if its not being used by driver | GitHub issue microsoft#525
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:
Here's how I terminate the TCP connection from the app host. Basically don't respond to the TCP keepalives:
To determine when SQL Server terminates the connection, I use this query:
The text was updated successfully, but these errors were encountered: