Reuse open connection from BasicDataSource - java

I am creating a new BasicDataSource object and set in it username, password, etc.
Once i call the dataSource.getConnection(), a new connection is created.
My requirement is to able to reuse the already opened connection.
In the Java Doc of getConnection() it is written:
Create (if necessary) and return a connection to the database
Which apparently i can't understand WHEN is this necessary.
There is a setMaxActive that limits the maximum connections, but this looks to be kind of limiting currently for me as once the getConnection() is called, it tries to create a new connection with the database instead of getting the existing one.
Question: Is there away to set somehow the DataSource in that way in order to create just one connection and to retrieve the same connection always when getConnection() is called ? Any other workaround ?

Related

Is there any way to use connection pool in Jsoup?

I am working on a project which need to use jsoup to parse html source. I found it create a new connection every time.
public static Connection connect(String url) {
Connection con = new HttpConnection();
con.url(url);
return con;
}
Is there anyway to use a shared connection just like JDBC connection pool?
In JDBC, all the connections are made to the same database instance so it's logical to group those together and create connection pool (as processes can re-use the connections).
However, in the above example, we are making a connection per url and hence, each connection will be separate and won't be reusable. So, in this case, it makes sense to create a new connection.

How to get current Connection object used by jdbcTemplate

I am looking for a way to intercept the connection that JDBCTemplate creates internally i.e. the connection that is created when the function getConnection() is called by JDBCTemplate.
ex: if I use jdbcTemplate.update(query); I want to get the information of the connection that was used to complete this update statement. Is there a way to see the metadata of the connection mid or post execution of this statement ? I am using C3P0 connection pool.
Many people have suggested using DataSourceUtils.getConnection() , but that just fetches a new connection from the pool and does not solve my issue.
This thread also effectively asks the same question: How to get current Connection object in Spring JDBC
jdbcTemplate.getDataSource().getConnection();
By using the above line we can fetch the connection object.

How to properly keep a DB connection from a Connection Pool opened in JBoss

I'm using JBoss AS 7.1 as a server and I have my DataSource configured with pooling. I'm quite new to this so please excuse any rookie mistakes... after all I'm here to learn.
When a client logs-in it gets a connection to the database and I need to keep that connection(from the pool) open until the user logs-out or the HttpSession expires. This is an absolute requirement coming from our DB Admin. who says that he needs the DB session variables. I am using a servlet for all this.
Playing with the possibilities I have encountered 2 major problems:
As far as I see JBoss automatically closes unused connections => my opened connection returns to the pool. So this might not be the right path.
If I try to store/recall the Connection object like this:
private Hashtable<String, Connection> connections = new Hashtable<String, Connection>();
try {
String strDSName1 = "java:/OracleDSJNDI";
ctx = new InitialContext();
ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
System.out.println("Got 1'st ds.");
} catch (Exception e) {
System.out.println("ERROR getting 1'st DS : " + e);
}
connection = ds1.getConnection();
connections.put(session.getId(), connection);
conn = (Connection) connections.get(sessionID);
it throws this exception:
java.sql.SQLException: Connection is not associated with a managed
connection.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6#dee1f37
My question is: How do I properly keep my connection opened?
Thanks
How do I properly keep my connection opened?
You must not do that, let the connection pool handle this.
Behind the scenes, the connection pool will keep a bunch of database connections to the database engine (MySQL, Oracle, SQL Server... depends how you configure it) in SLEEPING state. When you execute this code:
//avoiding all the particular exceptions just for code simplicity purposes...
//in real world applications, you must handle each of these exceptions
public Connection getConnection() throws Exception {
ctx = new InitialContext();
ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
return ds1.getConnection();
}
You're asking to the connection pool to retrieve one of these connections available. The connection pool will give you a database connection (if available) and let you use it as long as you want. Then you use it wherever you want/need and close it:
public void foo() throws Exception {
Connection connection = getConnection();
//do what you want/need...
//in the end, you close the connection
//this is A MUST!
connection.close();
}
When executing connection.close() from a connection retrieved by the connection pool, you're not closing the physical database connection but notifying the connection pool this specific database connection must return to the SLEEPING state.
Some advices from the explanation:
You must not try to keep the connection alive, that's connection pool's job.
You must not try to store the connections in any cache-like structure, that's connection pool's job.
You must retrieve a java.sql.Connection in the shortest scope you will need it. Once you have used it, close it.
Your DBA is basically requiring you to avoid connection pooling by making the database connection equivalent to the user's session.
So one option is to not use the connection pool, and instead roll your own functionality that opens/closes the database connection around the user's session. That seems complicated and unusual though.
Another option is to examine the DBA's requirement. The DBA may have to adapt to the idea that he'll need to track state in a different way, e.g. by using a key related to the session to store the state he needs in a table, instead of storing state in the connection layer.
Generally speaking storing state in some component's session handling is adding indirect complexity, because you start having to care about how the component handles expiry and uniqueness, as you're finding here where the HTTP session state handles this differently from the database session.

How do I recreate a mysql data source connection, if the connection fails, in java?

I have created a mysqlDatasource connection using the following code:
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
If Im running my application and the connections are disconnected because mysql restarted or for some other reason, the remaining operations will fail even if the mysql server instance is running.
In that case I want to recreate a connection? Is this possible? How do I go about doing this?
In most cases when you're creating multiple connections and juggling them, it's better to use a connection pool, where the Connection objects are just that, objects, and are multiplexed to actual socket connections handled by an underlying implementation. This means that connections are created automatically when you need them and you don't need to worry about reclaiming resources and creating an appropriate number of connections.
Two prominent examples are BoneCP and C3P0.
The other option, in addition to Mr Mao's, is to define the url explicitly using setURL to allow for automatic reconnection, using the autoReconnect parameter, do note, though, that this approach is not recommended. The answer is provided here only for completeness.
Just take an help of DBCP CONNECTION and create your Connection pool like below code. You can see there is validation query which pings database at regular interval and refreshes the pool. There are other property like validateConnection you can set this property to true.
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setUrl("jdbc:mysql://<host>:<port>/<database>");
dataSource.setMaxActive(50);
dataSource.setMaxIdle(5);
dataSource.setInitialSize(5);
dataSource.setValidationQuery("SELECT 1");
Try this.
String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
Class.forName(driver);
String url = "jdbc:microsoft:sqlserver://host:1433/database";
Connection conn = DriverManager.getConnection(url, "username", "password");

How to verify the connection object returned from connection pool?

I am doing jndi lookup for datasource configured in JBOSS AS.Code for which is as below.
initialContext = new InitialContext(props);
dataSource =
(DataSource)initialContext.lookup(bundle.getString("jndiName"));
connection = dataSource.getConnection();
This snippet of code is placed in doPost of servlet. Also i am safely calling
connection.close()
after using connection object.
My datasource config has following entries
<min-pool-size>1</min-pool-size>
<max-pool-size>1</max-pool-size>
As per my understanding of connection pooling, each time i make a request to servlet same connection object is returned by datasource .getConnection() call(Since i have specified min and max pool size to be 1 and a call to close does not close the DB connection altogether).
Now how do i verify that same connection object is being returned?
You actually can't be sure that it is the same connection. It maybe problems with connection with database, so another connection had to be created. Why you want to verify connection? Maybe you could save hash value and compare them?

Categories

Resources