Understanding JDBC Timeout Variables and replication - java

I am using JDBC driver to connect to mySql from my java code (read client).
Driver = com.mysql.jdbc.Driver
JdbcUrl = jdbc:mysql://<<IpOftheDb>>/<<DbSchema Name>>?autoReconnect=true&connectTimeout=5000&socketTimeout=10000
In case the database is down ( machine hosting the db is up but the mysqld process is not running) , it takes some time to get the exception , The exception is
"com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Could not create connection to database server. Attempted reconnect 3 times. Giving up."
In the statement above socketTimeout is 10 sec . Now if I bring up the db with 10 sec as SocketTimeout I get the response correctly.
But If i reduce it to one sec and am executing the query I get the same exception.
"com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Could not create connection to database server. Attempted reconnect 3 times. Giving up."
But connectTimeout doesnt change anything. Can someone explain me what socketTimeout and connectTimeout means.
Also , If we are setting up replication and specifying the 2nd database as failover i.e.
my connection string changes to
jdbc:mysql://<<PrimaryDbIP>>,<<SecondaryDbIp>>/<<DbSchema>>?useTimezone=true
&serverTimezone=UTC&useLegacyDatetimeCode=false
&failOverReadOnly=false&autoReconnect=true&maxReconnects=3
&initialTimeout=5000&connectTimeout=6000&socketTimeout=6000
&queriesBeforeRetryMaster=50&secondsBeforeRetryMaster=30
I see that if primary is down then I get the response from secondary (failover Db) .
Now when client executes a query , does it go to primary database and then wait for socketTimeout (or whatever) and then goes to Secondary or it goes to Seconday before timeout occurs.
Moreover, the second time when the same connection Object is used , does it go directly to the secondary or again the above process is repeated .
I tried find some documentation which explains this but couldnt get .
Hopefully , someone can help here explaining the various timeout parameters and their usefulness.

Related

Weird behaviour of connectTimeout in mysql Spring Boot

I want to implement Database connection timeout in my spring boot application so that whenever establishing connection to the Database takes more than a certain time, it should throw a timeout exception and it should not wait indefinetely. I am using mysql as database. In my JDBC URL I have mentioned the parameter "connectTimeout" like this:
datasource.jdbc-url=jdbc:mysql://XX.XX.XX.XX/dbName?connectTimeout=5000
In the official docs, its mentioned that the unit is in milliseconds. Now I have measured the database connection time in my local to be around 1400ms.
stopwatch.start();
datasource.getConnection();
stopwatch.stop();
So ideally, setting connectTimeout to be less than 1000 should throw timeout exception. But it does not throw any error even after giving a value as low as 10.
Only when I mention the value to be 1, then it throws me timeout exception.
datasource.jdbc-url=jdbc:mysql://XX.XX.XX.XX/dbName?connectTimeout=1
Which gives me the notion that maybe the timeout is being considered in seconds? Am I doing anything wrong here?
Mysql Connector Verion: 5.1.46
Docs Link: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-networking.html

java.sql.SQLException: Could not find database ID X name 'database'.

When I run all my JUnit tests, which uses a MS SQL Server database, I'm getting the following error:
java.sql.SQLException: Could not find database ID X, name 'database_name'. The database may be offline. Wait a few minutes and try again.
or sometimes the java.sql.Connection object is closed unexpectedly.
I got rid of the problem when I turned AUTO CLOSE setting to OFF, right after database creation:
CREATE DATABASE TEST123;
ALTER DATABASE [TEST123] SET AUTO_CLOSE OFF WITH NO_WAIT;
Check it out: Worst Practice: Allowing AutoClose on SQL Server Databases

jdbc connectTimeout vs jdbc loginTimeout

There is a requirement in our project to support 'jdbc timeout' feature for Postgres (Postgresql driver).
we also support Microsoft SQL (JTDS driver) and MySQl (mysql driver). So i want to introduce the 'loginTimeout' as a common feature for all the Databases.
While going through documentation of the drivers, i found there is a jdbc parameter called 'loginTimeout' supported from both JTDS and Postgresql drivers but not for Msql
http://jtds.sourceforge.net/faq.html
loginTimeout (default - 0 for TCP/IP connections or 20 for named pipe connections) The amount of time to wait (in seconds) for a successful
connection before timing out. If a TCP/IP connection is used to
connect to the database and Java 1.4 or newer is being used, the
loginTimeout parameter is used to set the initial connection timeout
when initially opening a new socket. A value of zero (the default)
causes the connection to wait indefinitely, e.g.,until a connection is
established or an error occurs. See also socketTimeout. If a named
pipe connection is used (namedPipe is true) and loginTimeout is
greater than zero, the value of loginTimeout is used for the length of
the retry period when "All pipe instances are busy" error messages are
received while attempting to connect to the server. If loginTimeout is
zero (the default), a value of 20 seconds is used for the named pipe
retry period.
http://jdbc.postgresql.org/documentation/84/connect.html
loginTimeout = int Specify how long to wait for establishment of a
database connection. The timeout is specified in seconds.
but for Mysql there is nothing like loginTimeout, but has
connectTimeout: Timeout for socket connect (in milliseconds), with 0
being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'
So my question is "what is the difference between connectTimeout and loginTimeout" , do they do the same functionality ?
MySQL's socketConnect setting determines how long the client will try to attempt to open a network connection; it makes no claims that the database itself will authenticate or function, only that a socket can be established.
Postgres, by contrast, is indicating a maximum amount of time to connect to the database; if your command returns before the timeout, then the database received the network request and responded in an appropriate amount of time.
So in one situation, you are only putting constraints on network behavior (i.e. how long you wait to connect a socket to that server at that port); in the other, you are putting constraints on database behavior (i.e. how long to wait for the database itself to connect).
As a side note, the interface javax.sql.CommonDataSource dictates a JDBC property for getLoginTimeout which mimics the behavior of PostgreSQL's property. When you look at various implementations of a MysqlDataSource(mariadb, for example), these methods are not implemented; this generally leads me to believe that there is no direct analogue in MySQL.

Query timeout on MS SQL Server

I have a Java webapp accessing MSSQL database on a MS SQL Server 2012 running on the same machine.
Some of the queries fail after exactly 3 seconds with:
com.microsoft.sqlserver.jdbc.SQLServerException: The query has timed out.
It happens a couple of times a day, in the mornings, when the app is not heavy loaded.
On average the queries took less than 50 ms.
I'm using Microsoft JDBC Driver 4.0 and the queries will fail after exactly 3 seconds even if I use statement.setQueryTimeout(0);
Remote query timeout on the server is set to its default value (600s).
Any idea why the queries fail after 3s?
Edit:
Here are some of the queries:
UPDATE CampaignCalls SET note = 'Short Text' WHERE (saveTime IS NULL) AND (agent = ?)
This one updates no more than 50 rows
INSERT INTO CampaignCustomers (campaignId, clientId, completed, callTime)
SELECT ?, clientId, 0, callTime
FROM CampaignCustomers WITH (NOLOCK) WHERE campaignId = ?
This one copies no more than 1500 rows.
The connection to the server doesn't break. I'm reusing it a moment later with no problems.
I am wondering why the 3 seconds? Is there any other timeout setting I am not seeing? Even if the table is locked for some reason, why is the query timing out after exactly 3s?
Thank you all!

Set timeout for Statement.executeBatch

I would like to find out how I can set a timeout for a Statement.executeBatch() in Java. The code works well when the database is up, but when I block the db IP in iptables, the JVM hangs at executeBatch(). I tried using .setQueryTimeout(10) but an exception is thrown:
SQLException cannot be cast to SybSQLException
On database side I use Sybase and jdbc2 for connection
Thank you.
PS: I can't post the code because it is company copyrighted.

Categories