Does getConnection always open a new connection? - java

I have found this method in a Java file and I am wondering what's happening here? Does this really work? I think this method does nothing because the getConnection()-method creates a new connection and then it gets closed. Am I correct?
public void closeAllConnections()
{
for(String db : this.dbList)
try {
DataSource ds = (DataSource) this.applicationContext.getBean(db+"DataSource");
ds.getConnection().close();
} catch (Exception e) {
//...
}
}

It depends how your DataSource is defined.
If it uses connection pooling it can reuse existing connection
for example see oracle explanation
Connection pooling in the JDBC 2.0 extension API is a framework for
caching database connections. This allows reuse of physical
connections and reduced overhead for your application.

Related

How to avoid inactive sessions using wso2 connection pool on oracle?

I have a small set of custom WSO2 ESB mediators which use an oracle database to which I'm connecting via WSO2 Data Source like this:
private void Connect(boolean isRetry) throws SQLException {
DataSource ds = null;
try {
Hashtable environment = new Hashtable();
environment.put("java.naming.factory.initial", "org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory");
Context initContext = new InitialContext(environment);
ds = (DataSource)initContext.lookup("jndi/kernel");
} catch (NamingException e) {
throw new SQLException("Connection pool exception", e);
}
// Nawiazanie polaczenia
this.connection = ds.getConnection();
this.connection.setAutoCommit(false);
}
After using the connection I'm closing it like this:
public void Close() throws SQLException {
try {
if (this.connection != null) {
this.connection.close();
this.connection = null;
}
} catch (SQLException e) {
System.out.println(" ## Failed to close the connection!");
e.printStackTrace();
throw e;
}
}
Every custom mediator is using the above Connect method on the begining and Close method in the finally scope at the end.
In a single sequence (executed by a message processor) there are at least 2 custom mediators called, sometimes even 5.
The problem is that when there are a lot of messages passing through the queue there are hundreds of inactive session on the database (oracle). It looks like the Connect method doesn't try to get an inactive connection and use it and I thought that this is the whole point of having a connection pool.
Any help will be much appreciated..
I currently have a custom mediator that needs to get a connection on oracle db.
I don't have this problem of inactive sessions although this mediator is used in a sequence executed by a message processor (processing thousands of messages)
Don't know exactly what is wrong in your case but I hope this can help you :
the datasource is defined in WSO2 ESB with the web console.
The Driver used is oracle.jdbc.OracleDriver
A validation query is defined (select 1 from dual)
test on borrow is set to true
max active is a positive number
remove abandoned is set to true
and of course, the data source is exposed as a JNDI Data Source
In the java part, I don't use directly InitialContext to made a lookup : I use org.apache.synapse.commons.datasource.DataSourceFinder.find(dataSourceName, jndiProperties) where jndiProperties is just a new Properties()
In the finally, I just need to close resultset, statement and connection
It works well with ESB 4.8.1 and ESB 5
The problem was that I had "test on idle" set to true. After turning it off everything is fine now.

sharing a JDBC Connection object between other objects

I have created a Database class which uses a static connection object in order to be used in common between instances of itself. my question is that is there any problem with this approach or not?
class Database {
private static Connection connection = null;
public Database() {
if(connection == null){
...
connection = DriverManager.getConnection(...);
...
}
}
}
If you are going to have many (hundreds) of queries per second then implementing a connection pool is the way to go. See the answer to this question for more details. However, if you a Java novice (we all were one day!) then I don't imagine you will be needing this requirement, and probably will struggle to implement it.
Instead, the simple pattern of creating a new connection if required, and then closing it when finished will be the best way to go forward for you. Below is a modified version of your Database class which I think is a good way to move forward.
class Database {
private Connection con = null;
private final String connectionString;
public Database(String connectionString) {
this.connectionString = connectionString;
}
public void connect() throws SQLException {
if (con != null // if the connection exists
&& !con.isClosed() // and has not been closed
&& con.isValid(0)) { // and appears to be functioning (with a test timeout of 0ms)
return; // skip connection creation
}
// create the connection
con = DriverManager.getConnection(connectionString);
}
public void testFunction() {
try {
connect();
// .. do some stuff with the connection ..
} catch (Exception e) {
// log or otherwise deal with the error
} finally {
try {
con.close();
} catch (Exception e) {
System.err.println("Failed to close connection: " + e.toString());
}
}
}
}
Some things to note about this solution:
It is not very efficient - creating a new connection always takes more time than using an existing one
This class if not thread safe - if you need this requirement, I recommend using a thread pool. However, if you create a new instance of this class per thread then it will be thread safe (as there is not static connection to worry about!)
It does do the job - certainly for simple cases. I use the model for a relatively low volume database which has approx 50-100 connections made/closed per minute and it does not add a noticeable lag
It is very robust - nothing is safer than opening and closing a connection per query. You are guaranteed to be able to handle a connection failure per query, and the connection will always be closed (unless it already has been).
Disclaimer The solution above is not a particularly amazing solution. However, I believe it is simple to implement and a good way for a Java novice to get to know the ropes before jumping into external libraries.
There is nothing wrong with creating an object to manage your connections, however, connections should be opened and closed and can be used in multi-threaded environments, so having a static connection is not a good idea. For a method that needs a connection, get a connection use it, close it. Even if you are not using it in a multi-threaded environment, the connection can time-out, then you need to constantly check if the connection is up and available, instead of just saying, get me a connection, use the connection, close it.

Problem with singleton database connection

I'm using singleton design-pattern for my database connection.
Here is my method.
private static Connection con=null;
public static Connection getConnection(){
try {
if(con==null){
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "");
}else if(con.isClosed()){
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "");
}
} catch (Exception ex) {
}
return con;
}
Whenever I restarted mysql service, it generates following error and have to restart the application also to run again.
Error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
Can anyone show what is the correct way of implementing this to avoid this error?
thank you.
You're reusing the same Connection object across... well, everything. Your singleton should be a ConnectionFactory that returns a new connection every time.
As someone already noted, rather than create/close new connections use a connection pool. You don't have to write it yourself—there are readily available open-source implementations such as C3PO or DBCP.
Even better, rather than reinventing this wheel all over again, use a DataSource. If you can use Spring, it has a DriverManagerDataSource implementation just for this. Otherwise, feel free to look at how it's written and write your own (I've done this at least once when Spring wasn't an 'allowed' technology).
Finally, if you're running in a container such as Tomcat, JBoss or Glassfish, then you can simply bind a DataSource to JNDI and use that. This frees up your application from having to handle pooling and configuration/deployment issues (stuff like database user name & password) itself.
You should go for connection-pooling.
Your mechanism won't work if mysql server drops your connection some how.

A persistent connection with JDBC to MySQL

I have an application that connects to MySQL using JDBC. There are cases where the JDBC connection lies idle for hours (maybe even days) and its loosing its connection to MySQL and then excepts when it tries to execute a query. What is the best solution for this?
Keeping the connection open for an undertemined time is a bad practice. The DB will force a close when it's been open for a too long time. You should write your JDBC code so that it always closes the connection (and statement and resultset) in the finally block of the very same try block where you've acquired them in order to prevent resource leaking like this.
However, acquiring the connection on every hiccup is indeed a pretty expensive task, so you'd like to use a connection pool. Decent connection pools will manage the opening, testing, reusing and closing the connections themselves. This does however not imply that you can change your JDBC code to never close them. You still need to close them since that would actually release the underlying connection back to the pool for future reuse.
There are several connection pools, like Apache DBCP which is singlethreaded and thus poor in performance, C3P0 which is multithreaded and performs better, and Tomcat JDBC for the case that you're using Tomcat and wouldn't like to use the builtin DBCP due to bad performance.
You can create connection pools programmatically, here's an example with C3P0:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dbname");
dataSource.setUser("username");
dataSource.setPassword("password");
Do it once during application's startup, then you can use it as follows:
Connection connection = null;
// ...
try {
connection = dataSource.getConnection();
// ...
} finally {
// ...
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
When you're running inside a JNDI-capable container like a servletcontainer (e.g. Tomcat), then you can also declare it as a java.sql.DataSource (Tomcat specific manual here). It will then use the servletcontainer-provided connection pooling facilities. You can then acquire the datasource as follows:
DataSource dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/YourDataSourceName");
There are libraries, such as Apache's DBCP which can do connection pooling. A part of this is they can be setup to automatically test the connection when you go to use it (such as "SELECT NOW() FROM DUAL", or something else harmless) and automatically re-establish the connection transparently if necessary, allowing your application to pretend that the connection is everlasting.
Check here:
http://download.oracle.com/javase/tutorial/jdbc/basics/connecting.html
Basically, you should use DataSource and always do a getConnection() before using it. DataSource, unless there's something terribly wrong, will reconnect if necessary.

Best way to manage DB connections without JNDI

I have a website, in which currently I am getting 1000 page views. I am expecting it will go around 30k per day in future. Now the problem for me to manage the DB connections.
At present I am just connecting to DB directly from java program. I know it is worst design in the world. But for time being I have written like that.
I have plan to manage connection pooling using JNDI. But the problem is my hosting provider is not supporting JNDI.
Can anyone suggest me how to manage DB connections without jndi?
Connection pooling does not per se require the connections to be obtained by JNDI. You can also just setup and use a connection pool independently from JNDI. Let's assume that you'd like to use C3P0, which is one of the better connection pools, then you can find "raw" JNDI-less setup details in this tutorial.
Here's an extract of the tutorial:
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("swaldman");
cpds.setPassword("test-password");
Create the datasource once during application's startup and store it somewhere in the context. The connection can then be acquired and used as follows:
Connection connection = null;
// ...
try {
connection = cpds.getConnection();
// ...
} finally {
// ...
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
Yes, closing in finally is still mandatory, else the connection pool won't be able to take the connection back in pool for future reuse and it'll run out of connections.

Categories