I am (successfully) connecting to a database using the following:
java.sql.Connection connect = DriverManager.getConnection(
"jdbc:mysql://localhost/some_database?user=some_user&password=some_password");
What should I be checking to see if the connection is still open and up after some time?
I was hoping for something like connect.isConnected(); available for me to use.
Your best chance is to just perform a simple query against one table, e.g.:
select 1 from SOME_TABLE;
Oh, I just saw there is a new method available since 1.6:
java.sql.Connection.isValid(int timeoutSeconds):
Returns true if the connection has not been closed and is still valid.
The driver shall submit a query on the connection or use some other
mechanism that positively verifies the connection is still valid when
this method is called. The query submitted by the driver to validate
the connection shall be executed in the context of the current
transaction.
Nothing. Just execute your query. If the connection has died, either your JDBC driver will reconnect (if it supports it, and you enabled it in your connection string--most don't support it) or else you'll get an exception.
If you check the connection is up, it might fall over before you actually execute your query, so you gain absolutely nothing by checking.
That said, a lot of connection pools validate a connection by doing something like SELECT 1 before handing connections out. But this is nothing more than just executing a query, so you might just as well execute your business query.
Use Connection.isClosed() function.
The JavaDoc states:
Retrieves whether this Connection object has been closed. A
connection is closed if the method close has been called on it or if
certain fatal errors have occurred. This method is guaranteed to
return true only when it is called after the method Connection.close
has been called.
You also can use
public boolean isDbConnected(Connection con) {
try {
return con != null && !con.isClosed();
} catch (SQLException ignored) {}
return false;
}
If you are using MySQL
public static boolean isDbConnected() {
final String CHECK_SQL_QUERY = "SELECT 1";
boolean isConnected = false;
try {
final PreparedStatement statement = db.prepareStatement(CHECK_SQL_QUERY);
isConnected = true;
} catch (SQLException | NullPointerException e) {
// handle SQL error here!
}
return isConnected;
}
I have not tested with other databases. Hope this is helpful.
The low-cost method, regardless of the vendor implementation, would be to select something from the process memory or the server memory, like the DB version or the name of the current database. IsClosed is very poorly implemented.
Example:
java.sql.Connection conn = <connect procedure>;
conn.close();
try {
conn.getMetaData();
} catch (Exception e) {
System.out.println("Connection is closed");
}
Here is a simple solution if you are using JDBC to get the default connection
private Connection getDefaultConnection() throws SQLException, ApiException {
Connection connection = null;
try {
connection = dataSource.getConnection ();
}catch (SQLServerException sqlException) {
// DB_UNAVAILABLE EXCEPTION
}
return connection;
}
Related
I have primitive get method for my database. I need to get course by its id and then close connection and statement.
public Course get(int id) throws ClassNotFoundException, SQLException {
try (Connection connection = ConnectionConfig.getDbConnection();
PreparedStatement statement = connection.prepareStatement(GET_COURSE)){
statement.setInt(1, id);
ResultSet course = statement.executeQuery();
course.next();
String result = course.getString(1);
return new Course(id, result);
}
}
I want to do it with try-with-resources. Will it work in this code or auto-closing won't work because of return statement in the block? On the other hand, I don't want to use return outside this block because method can return object with null field. What method form is the most effective and readable in this situation? Thank you in advance, I understand this is quite amateurish question)
Closing the connections code is usually written in finally block
Connection connection = null;
try {
connection = ConnectionConfig.getDbConnection();
//do all the stuff
}
finally{
connection.close()
}
The connection will closed by the try with resources block. The condition for that is that a given class implements AutoCloseable. And that is already the case.
As it can be seen here
I am very new to Java.
I have Java class which implements the Database(Postgres) related functionality.
The problem is if Database stopped and then restart then My this class throws SQLException as connection got reset(database is up and running).
Is there any way that after Database restarted; my class automatically Connection to database and work as expected instead of throwing SQLException.
Is there any way with Properties as parameter to DriverManager.getConnection().
Thanks
MAP
Use a try catch block to handle the SQLException. When you catch an SQLException, the program could wait a specified period of time and then try to reconnect, you could loop this as long as you want.
boolean connected = false;
// repeat until connected is true
while (!connected) {
try {
// put your connection code here
connected == true;
} catch (SQLException se) {
// sleep for 10 seconds
Thread.sleep(10000);
}
}
I have been learning about using MySQL within Java using Oracle JDBC and I am trying to get into the mindset of try/catch and pool cleanup.
I am wondering if the following code is the correct way to perfectly clean everything up or if you notice holes in my code that requires something I've missed. For the record, I intend to use InnoDB and its row locking mechanism which is why I turn auto commit off.
try
{
connection = getConnection(); // obtains Connection from a pool
connection.setAutoCommit(false);
// do mysql stuff here
}
catch(SQLException e)
{
if(connection != null)
{
try
{
connection.rollback(); // undo any changes
}
catch (SQLException e1)
{
this.trace(ExtensionLogLevel.ERROR, e1.getMessage());
}
}
}
finally
{
if(connection != null)
{
try
{
if(!connection.isClosed())
{
connection.close(); // free up Connection so others using the connection pool can make use of this object
}
}
catch (SQLException e)
{
this.trace(ExtensionLogLevel.ERROR, e.getMessage());
}
}
}
getConnection() returns a Connection object from a pool and connection.close() closes it releasing it back to the pool (so I've been told, still new to this so apologies if I am talking rubbish). Any help on any of this would be greatly appreciated!
Thank you!
I recommend not setting autocommit back to true in the finally block - your other threads that are relying on autocommit being set to true should not assume that the connections in the pool are in this state, but instead they should set autocommit to true before using a connection (just as this thread is setting autocommit to false).
In addition, you should check the connection's isClosed property before calling close() on it.
Other than that, I don't see any problems.
I have an app that I'm connecting to a MySQL database. It loses connection in the middle of the night and then spouts about null connections and JDBC hasn't received messages in X seconds.
I call getConnection() before I do anything that requires communication with the SQL server.
This is my getConnection() method:
private Connection getConnection() {
try {
if (connection != null) {
if (connection.isClosed() || !connection.isValid(10000)) {
this.initializeRamsesConnection();
}
} else {
this.initializeRamsesConnection();
}
} catch (Exception e) {
debug("Connection failed: " + e);
}
return connection;
}
In the initializeRamsesConnection() method I put the password and so on information into a string and then I create the connection in the standard JDBC way.
Then I call this method:
private Connection getConnectionFromConnectionString() {
Connection con = null;
String driver = "com.mysql.jdbc.Driver";
try {
Class.forName(driver);//jdbc sorcery
//if there is no connection string
if (getConnectionString() == null) {
HMIDatabaseAdapter.debug("No connection string");
}
//makes a string out of the values of db/host
String str = getConnectionString();
//if there is no driver
if (driver == null) {
debug("" + ": " + "No driver");
}
//Tries to make a connection from the connection string, username, and the password.
con = DriverManager.getConnection(str, username, password);
//if for some reason the connection is null
if (con == null) {
HMIDatabaseAdapter.debug("CONNECTION IS NULL, WHAT?");
}
} catch (Exception ex) {
HMIDatabaseAdapter.debug("getConnection() " + ex);
}
return con;
}
What can I change in either of these methods to accommodate losing connection?
This is not the correct way of retrieving a connection. You're retrieving the connection and assigning it as an instance (or worse, static) variable of the class. Basically, you're keeping the connection open forever and reusing a single connection for all queries. This may end up in a disaster if the queries are executed by different threads. Also, when it's been kept open for too long, the DB will reclaim it because it assumes that it's dead/leaked.
You should acquire and close the connection in the shortest possible scope. I.e. in the very same try block as where you're executing the query. Something like this:
public Entity find(Long id) throws SQLException {
Entity entity = null;
try (
Connection connection = dataSource.getConnection(); // This should return a NEW connection!
PreparedStatement statement = connection.prepareStatement(SQL_FIND);
) {
statement.setLong(1, id);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
entity = new Entity(
resultSet.getLong("id"),
resultSet.getString("name"),
resultSet.getInt("value")
);
}
}
}
return entity;
}
If you worry about connecting performance and want to reuse connections, then you should be using a connection pool. You could homegrow one, but I strongly discourage this as you seem to be pretty new to the stuff. Just use an existing connection pool like BoneCP, C3P0 or DBCP. Note that you should not change the JDBC idiom as shown in the above example. You still need to acquire and close the connection in the shortest possible scope. The connection pool will by itself worry about actually reusing, testing and/or closing the connection.
See also:
Am I Using JDBC Connection Pooling?
JDBC MySql connection pooling practices to avoid exhausted connection pool
Where in your code are the errors on losing connection coming from? This would probably be the best place to start.
Off the top of my head (and I may be wrong), JDBC connections will only close on an actual fatal error, so you won't know they've failed until you try to do something.
What I've done in the past is to invalidate the connection at the point of failure and retry periodically.
Maybe this is what you are looking for:
http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html
For java see autoReconnect:
http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html
I am using JDBC to connect to a DB. Since the network was slow, i could get the connection after some 2 or 3 retry manually. Is it possible to retry the connection automatically if connection fails? I am using SQLServer 2008 database.
Thanks
A bit decent connection pool is already configureable to do so, for example BoneCP. Most do even do it by default. If you don't use a connection pool but just the basic DriverManager#getConnection() approach, then you have to re-execute it yourself in a while loop as long as the Connection is null.
Here's a basic kickoff example:
Connection connection = null;
while (connection == null) {
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
logger.info("Connecting failed, retrying...");
}
}
return connection;
This can of course be optimized more with bit longer pauses in between and by setting a maximum retry count, etcetera.
Here the code by which it re-try it 3 times to connect,you can also change the cont instead of 3 this can be changed to any number of times(5,10 etc)
Connection connection = null;
while (connection == null && count<3){
try {
String Connection="jdbc:sqlserver://"+serverip+';'+"database="+dbName+';'+"user=" +Username+';'+"password=" +Password;
Class.forName(classname);
connection = DriverManager.getConnection(Connection);
}catch (SQLException e){
count++;
System.err.println("Connecting failed, retrying...");
}
}
count=0;
return connection;
}