I am trying to research this issue on the following two errors connecting to Oracle DBs:
Closed Connection
java.sql.SQLException: Io exception: Socket read timed out
My understanding:
Closed Connection : Is occurring either because there was some sort of network disruption or the DB closed the session due to some sort "inactivity"
java.sql.SQLException: Io exception: Socket read timed out : This is a case where the connection was made successfully but for some reason the socket/data was empty and eventually it timed-out because no data was available.
Is it possible to replicate the above errors in a local Oracle DB env ? What are the steps ?
I appreciate you taking the time to respond.
Thanks.
Your understanding on closed connection is right. reason for closed connection: External devices such as firewall, network devices, and remote database listeners can force network connections to close after a period of inactivity
ReadTimeOut will happen even on active connections. If a query or procedure is taking lot of time, you will get read time out exception.
Closed Connection : Shutdown the database listener when database is running
ReadTimedOut : Add sleep in procedure for more than 10 minutes and call that procedure from application
Replication of Socket read time out error in Oracle DB env:
setNetworkTimeout for SQL connection // for example sake, set timeout as 120 seconds
Call a database procedure from java and sleep in that procedure for time more than setNetworkTimeout
dbms_lock.sleep(125); -- sleeps for 125 seconds
Since procedure is not returning with-in 120 seconds due to 125 seconds sleep, java will throw socket read time out in above scenario.
I have just started working with the java.sql.* package, but here is what I understand. A closed connection is an error that occurs and the DB session closes, but no error handling is done so that is the end of it. With java.SQException you can manage this error (use a throws clause) and print it out or do other error handling methods.
Here is a link from Oracle about Exceptions and how to handle them.
Hope this helps.
Exceptions in Java.
Related
I run a java programm and try to use it with a hosted DB, I run the Vserver ubuntu 12.04 with Mysql myself, full root-access.
I changed the my.cnf to have more resources.
When I start the application it is fast, hardly any difference to a local database.
My problem is that after a while of inactivity the program freezes probably because the connection dropped.
There is no entry in any errorlog. If I kill the application and restart it, it is working again, nothing else but kill works, it is a linuxPC.
I used ?autoReconnect=true but I am not sure this is correct, the tables are innodb.
Does anyone have an idea how to avoid the connection to drop or how to make sure a reconnection is made?
PS [17.12.2015]
?autoReconnect=true was removed
today I got some details after a long wait
com.openbravo.basic.BasicException:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 2.435.471 milliseconds ago. The last packet sent successfully to the server was 959.832 milliseconds ago.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet successfully received from the server was 2.435.471 milliseconds ago. The last packet sent successfully to the server was 959.832 milliseconds ago.
java.net.SocketException:
Is this what happens when wait_timeout is too short?
After the "error" the program worked again!
Your question lacks specific info, but I guess what is happen. MySQL Server has a parameter called wait_timeout (See official doc).
When you have a connection that exceed that timeout, MySQL will close it, and if you don't manage SQLExceptions properly, your application will have problems.
You can try to increase wait_timeout or review your connection code to manage exceptions, but both are workarounds.
I wouldn't recommend you to relay on autoReconnect as an alternative for any problem, instead it would be better to encapsulate connection management into business logic in order to manage open/close connection every time you need. Maybe connection pooling can help you.
I mean, when you call a business method from you UI (it doesn't mind if it is web, ws, desktop or whatever) you have to manage open connection and start transaction, (and other cross cutting concerns as authorization, audit, log, ...). During all businesses logic, control possible exceptions, commit or rollback and free resources.
If you post some code, you will get more specific answers.
Hope it helps!
autoReconnect is dangerous for InnoDB. When the connection is lost in the middle of a transaction the previous actions in the transaction are rolled back. But the code proceeds to run as if the transaction continues. This can lead to subsequent writes not being consistent with the rolled back data.
You would be better off recognizing the lost connection and restarting the transaction.
This question already has an answer here:
jdbc mysql loginTimeout not working
(1 answer)
Closed 7 years ago.
java.sql.DriverManager has setLoginTimeout method, but in the source code I can see that DriverManager only saves timeout in a field but never uses it.
I also tried to connect to a stopped MySQL Windows service with 10 sec timeout
DriverManager.setLoginTimeout(10);
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=root");
but exception is thrown after one second, timeout is ignored.
What is the correct way to set LoginTimeout or it is not supported at all?
There are several related factors:
1) DriverManager.setLoginTimeout() (your JDBC driver behavior)
... and ...
2) TCP/IP (your network stack's behavior)
If your turn mySQL "off", then connections to that port (e.g. 3306) will fail immediately. That's what you're seeing.
If you start a service on that port - and you somehow prevent it from responding to connection requests - that's when you'll see the JDBC login timeout.
Your questions are answered by the javadoc of setLoginTimeout (emphasis mine):
Sets the maximum time in seconds that a driver will wait while attempting to connect to a database once the driver has been identified.
The DriverManager itself doesn't do anything with the loginTimeout. It is up to individual JDBC driver to implement timeout handling and use the value of this property of DriverManager. So it is correct that you don't see any use of the value in the DriverManager itself. You'd need to check the source of the driver you are using.
The login timeout is is a maximum timeout, that is used for detecting non-responsive systems (eg the network connection is made, but the connection or login handshake stalls). When you attempt to connect to a stopped MySQL server, there is no system listening, and no network connection can be made and this is detected almost immediately.
but exception is thrown after one second, timeout is ignored.
DriverManager#setLoginTimeout(int)
Sets the maximum time in seconds that a driver will wait while
attempting to connect to a database.
This method set the login timeout used by JDBC drivers.
This sets the timeout for how long the Driver has to wait before the database returns a connection.If you attempt to login and database does not respond within 10 seconds it timeouts.As your service is stopped it immediately gets response as connection can not be established.So,ultimately it waits for database to respond to the login attempt for 10 seconds if it does not get connection it timeouts.
EDIT
As I have said above your service is stopped it can detect immediately irrespective of your logIn timeout and throws the Exception.
I know this sort of question has been asked for a few times, I read some of them but did not get any smarter.
My Java application is connecting to a database server via JDBC through a SSH Tunnel. The tunnel is opened once at beginning. When starting I opened the database connection everytime it is used. Due to changes in the app I needed the connection opened on startup and decided to keep it open until my application is closed. When I close the app I sometimes, not always, get following error:
- Could not retrieve transation read-only status server
java.sql.SQLException: Could not retrieve transation read-only status server
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 369.901 milliseconds ago. The last packet sent successfully to the server was 8 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
Could this be because of the always open database connection? I test the application only for short times. It will run on 4 computers all day long. Can I expect this error more often then? The connection is used every few minutes, so it should be more performant to keep it open, but maybe during break it is not used for half an hour.
What would you recommend me to do? Always reopen the connection or keep it like it is and find a workaround when I get this error? Do you maybe have another idea why this error appears?
Just ask if you need more error log, database code or whatever you need.
Thanks!
I'm going to say yes, your issue is probably due to the fact that you have a persistent connection open.
I took over a website a while ago and the guy before me had the same idea: Open a single connection, send the queries through it when needed, and never close it. A month after I took over the site, the database wouldn't return any more query results just like this.
As a general rule of thumb and for good programming practice, always clean up after yourself. If you're not using a variable, set it to null and delete it. Not using a connection? Terminate it. This is way less prominent in Java than it is in C++ as Java does all the cleaning up for you for the most part.
I am trying to insert the tens of millions of data into oracle database by through java application but after 850k data inserted I am getting the error:
java.sql.exception: IO Exception :Connection reset by peer socket
write error.
I have a similar issue in my aplication.
In my case, after a few minutes in which the connection has not used, oracle server resets the connection and when I had to use it again, this exception was thrown.
I found that the problem was that oracle sets the timeout for connection at 10 minutes in sqlora.net file.
Maybe you can try to increase this time interval or check if the connection is still valid instead to check if it is closed (a connection can be not valid even if it is not closed).
The last option works fine for me.
I hope this helps.
In my application I use connection to Oracle, when connection lost and I try to re-connect I receive exception:
java.sql.SQLException: Io exception: Broken pipe
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:124)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:161)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:273)
at oracle.jdbc.driver.T4CStatement.fetch(T4CStatement.java:540)
at oracle.jdbc.driver.OracleResultSetImpl.close_or_fetch_from_next(OracleResultSetImpl.java:264)
at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:196)
For recover I need to restart application, does it possible recover without restart?
Thanks.
Followings could be the possibilities which could be causing the exception:
Network problem: That is the network between the database and application server causing the physical connection to be dropped after a period of time. It's probably due to a firewall running behind the network which is configured to kill db connections after a specified period of time. You may consider a workaround to maintain the connection alive all the time simply by re-configuring your application server. For Tomcat, you may try adding validationQuery="select 'validationQuery' from dual in the Tomcat datasource conf file (context.xml)
The connections to the database server are being reset and the client is not notified by the database driver. The problem in this case is that the Oracle driver is discovering that it's socket to the DBMS somehow (firewall again, maybe?) has been closed by the other end. You may consider setting your connection timeout (in the pool) shorter than the network/DB server timeout as a solution.