I'm trying to make a connection pool following this link:
http://192.9.162.55/developer/onlineTraining/Programming/JDCBook/conpool.html
I don't understand something:
Somewhere in the class JDCConnectionDriver implements Driver you can find this method:
public static final String URL_PREFIX = "jdbc:jdc:";
public Connection connect(String url, Properties props)
throws SQLException {
if(!url.startsWith(URL_PREFIX) {
return null;
}
return pool.getConnection();
}
so, if you use mysql (for example), the url it will always start with jdbc... so the method connect it will never return you a connection...
Why is that?
Also I would like to ask you which is the best connection pooling framework...
so, if you use mysql (for example),
the url it will always start with
jdbc... so the method connect it will
never return you a connection... Why
is that?
This driver is specifically written to connect to a JDC Connection. That's why. It's looking for a url starting with jdbc:jdc: and not just jdbc:.
Also I would like to ask you which is
the best connection pooling
framework...
The most well known Connection Pooling library out there and used on many application servers and servlet containers is Apache Object Pool. The most common connection pooling is Apache DBCP (DataBase Connection Pooling).
Also, as stated by Rocky Triton, c3p0 is another JDBC library that included Connection and Statement Pooling.
Related
I have two local databases I'm trying to connect to using Java's Connection class. It's easy enough to connect to the first database using:
public Connection conn;
conn = DriverManager.getConnection(connectionString);
How can I add a second database to that same connection? They're both on the same server so it should be fairly simple but I can't find the right commands to do it.
Thanks
A Connection is a session with a specific database. You can't use one Connection to communicate with two different databases; for that, you need two separate Connections.
Connection conn1 = DriverManager.getConnection(connectionString1);
Connection conn2 = DriverManager.getConnection(connectionString2);
Have you tried:
public Connection conn1;
conn1 = DriverManager.getConnection(connectionString1);
public Connection conn2;
conn2 = DriverManager.getConnection(connectionString2);
Instance members shouldn't be public.
Connection should be a local variable, not an instance member.
You can only connect to one database at a time with a single Connection. Ergo you need another Connection.
I think you have to use J2EE, JTA transaction manager to accomplish this.
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.
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.
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.
I just want to make sure that if I use the following, I am opening a separate DB session and not resuing the same one (for testing I need individual sessions).
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD);
each time I do the above code, I run my query, then do a connection.close()
So for example:
while(some condition) {
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD);
//now use the connection to generate a ResultSet of some query
connection.close();
}
So, each iteration of the loop (each query) needs its own session.
Is this properly opening separte sessions as I need (and if not, what would I need to add/change)? thanks
The javadoc says:
Attempts to establish a connection to
the given database URL
Slightly woolly language, and I suspect that this is up to the JDBC driver, but I'd be surprised if this did anything other than open a new connection.
I suppose it's possible for a JDBC driver to perform connection pooling under the hood, but I'd be surprised to see that.
In the case of the Oracle JDBC driver, this will open a new connection every time. This is a relatively slow process in Oracle, you may want to consider using a connection pool (e.g. Apache Commons DBCP, or c3p0) to improve performance.