I am working with DB2. I created ConnectionPool for it. Some of the queries required to be executed in "aumoCommit = false" mode.
Connection con = ConnectionPool.getConnection // wrapper
con.setAutoCommit(false);
PreparedStatment ps = con.prepareStatement(// query... );
ps.setString(...);
ps.executeUpdate();
con.commit();
ps.close();
con.close();
con.setAutoCommit(true); // should be here ?
Question is: should i add con.setAutoCommit(true) line in the end or C3P0 resets state of every closed(returned to pool) Connection?
Edit: after a few comments, I add that my question is: should con.setAutoCommit(false) call be there in general or c3P0 reset state of this connection and nexct time this connection will be in con.setAutoCommit(false) by default?
c3p0 always releases Connections with autoCommit set to true, per the JDBC spec.
In general, c3p0 endeavors to make it true that nothing you do during an ordinary client session will have any effect on future client sessions. Once a Connection is checked back into the pool, c3p0 fully resets and restores its state.
The only place you can define Connection state that "sticks" across client sessions is in a ConnectionCustomizer's onAcquire(...) method, called before any client Session has been initiated. But this only works for Connection attributes whose value is undefined by the JDBC spec. Since autoCommit is required by spec to be true of a new Connection, and JDBC transparent Connection pooling requires pooled and new Connections be indistinguishable in application semantics, freshly checked-out Connections always have autoCommit set to true.
Related
We have BoneCP library managing our connection pools. I'd like to know if the following statement will return the connection back to the pool.
statement = conn.createStatement();
....
lots of code.
....
Connection conn = statement.getConnection();
statement.close();
conn.close();
Will the above code close the connection and put the connection back into the pool?
Update:
I'm asking this question because when I run the statistics on connectionpool, i still see the conPool.getTotalLeased() showing that 2 connections are being used. But, I've closed the connections using the above mechanism.
The whole sense of a pool is to hold already established connections to your database. When you retrieve a connection from your pool you save the time to connect to your database.
What you are seeing is the pool holding your connections so it is all fine.
When you close your connection, it is only returned to the pool and marked as available for your next retrieval.
Yes it does moves the connection back to the pool. There was a mistake when getting the connection from the pool, fixed it, now i'm not seeing the 2 connections in the totalLeased() method.
Mistake that I found
conPool.getConnection(); // loitering connection which we see in the getTotalLeased();
..
Statement st = conPool.getConnection().getStatement(); //we have handle to this connection.
return st;
I'm having problems with the connection pool in Tomcat after a database outage.
There's this heartbeat service servlet that won't come back up after a database outage.
I've already tried the standard answer, and beyond, specifically:
Adding to the Resource section in server.xml
validationQuery="select 1 from dual"
testOnBorrow="true"
removeAbandoned="true"
removeAbandonedTimeout="120"
logAbandoned="true"
Trying to close the connection with a check to validity:
if (connection != null && !connection.isValid(10)) {
connection.close();
}
(Resulted in java.sql.SQLException: Connection is closed)
Trying to abort the connection (not sure whether done right)
if (connection != null && !connection.isValid(10)) {
connection.abort();
}
(Resulted in java.lang.NoSuchMethodError: java.sql.Connection.abort(Ljava/util/concurrent/Executor;)V)
Tries 2) and 3) show that indeed the connection is invalid, and it knows it. The question is - how to destroy it?
Tomcat version: 7.0.29
The pool will destroy the invalid connection for you thanks to "testOnBorrow=true" setting (note that the "Abandoned" settings only apply to connections which are not returned to the pool).
So this is how it should go:
servlet borrows connection, does queries and returns connection to the pool.
servlet borrows connection, database crashes, servlet receives all kinds of horrible SQL errors but still returns connection to the pool.
database has restarted
on next heartbeat, servlet borrows connection. Tomcat's pool will "test on borrow", find that the old connection is broken, removes (and closes) connection, tries another, finds that it is also broken, etc, and THEN the pool decides to create a new connection, test it OK and hands it over to the servlet.
servlet receives new valid connection, does queries and returns connection to the pool.
I'm not sure how Tomcat's pool behaves when a "test on borrow" indicates a connection is broken (1): it might not create new connections right away or throw an error when it can't get a valid connection from the pool. But I expect the pool to effectively flush itself and re-populate with new (valid) connection.
(1) That is, if the "test on borrow" is actually done which this post indicates is not the case ...
If the pool does not flush itself, you can try to do this programmatically once you find connections are invalid. I have not tried this before, hopefully you can get it to work. Following method is described here:
Reach into the JNDI context, pull-out the DataSource object, cross your fingers, cast it to org.apache.tomcat.jdbc.pool.DataSource, and call the purge() method.
Alterntively, use JMX and call the purge method via the MBean.
If you experience hanging threads after a database crash, you might have to resort to a work around described in this answer.
If we want to dispose an ill java.sql.connection from Tomcat jdbc connection pool,
we may do this explicitly in the program.
Unwrap it into an org.apache.tomcat.jdbc.pool.PooledConnection, setDiscarded(true)
and close the JDBC connection finally, the ConnectionPool will remove the underlying connection once it has been returned.
(ConnectionPool.returnConnection(....))
PooledConnection pconn = conn.unwrap(PooledConnection.class);
pconn.setDiscarded(true);
conn.close();
I have noticed some programmer using COMMIT other using conn.setAutoCommit(true); to end the transaction or roll back so what are the benefits of using one instead of the other?
Where is the main difference?
conn.setAutoCommit(true);
over
statement.executeQuery(query);
statement.commit();
You should in general use Connection.commit() and not Connection.setAutoCommit(true) to commit a transaction, unless you want to switch from using transaction to the 'transaction per statement' model of autoCommit.
That said, calling Connection.setAutoCommit(true) while in a transaction will commit the transaction (if the driver is compliant with section 10.1.1 of the JDBC 4.1 spec). But you should really only ever do that if you mean to stay in autoCommit after that, as enabling / disabling autoCommit on a connection may have higher overhead on a connection than simply committing (eg because it needs to switch between transaction managers, do additional checks, etc).
You should also use Connection.commit() and not use the native SQL command COMMIT. As detailed in the documentation of Connection:
Note: When configuring a Connection, JDBC applications should use the appropriate Connection method such as setAutoCommit or setTransactionIsolation. Applications should not invoke SQL commands directly to change the connection's configuration when there is a JDBC method available.
The thing is that commands like commit() and setAutoCommit(boolean) may do more work in the background, like closing ResultSets and closing or resetting Statements. Using the SQL command COMMIT will bypass this and potentially bring your driver / connection into an incorrect state.
The usage of conn.setAutoCommit(); applies to the connection and gives you the possibility to execute X queries in a single transaction, or use one single transaction per execute
As the API describes:
void setAutoCommit(boolean autoCommit)
throws SQLException
Sets this connection's auto-commit mode to the given state. If a connection is in auto-commit
mode, then all its SQL statements will be executed and committed as
individual transactions. Otherwise, its SQL statements are grouped
into transactions that are terminated by a call to either the method
commit or the method rollback. By default, new connections are in
auto-commit mode
For a simple case:
conn.setAutoCommit(false);
statement.executeQuery(query);
statement.commit();
will be the same as:
conn.setAutoCommit(true);
statement.executeQuery(query);
I have the following code in the Try bloc :
// Session variable
Session session = null;
// Connection variable
Connection conn = null;
try {
...
// Get hibernate session
session = getHibernateTemplate().getSessionFactory().openSession();
// Get connection frojm session
conn = session.connection();
...
}catch{
...
}
And in the finally bloc i want to bloc all the related object of the connection with the database.
the closing of session makes us to close the connection ? or we have to have to close the connection before ?
Solution 1 :
finally{
try{if (conn!=null) conn.close();}ctach{}
try{if (session!=null) session.close();}catch{}
}
Solution 2 :
finally{
try{if (session!=null) session.close();}catch{}
}
In case of one of the two solutions before, can you explain the relationship between session and connection specially through pool way.
Second approach is enough. If you haven't set hibernate.connection.release_mode, then default (auto) is used. According documentation:
By default, a JDBC connection is held until the session is explicitly
closed or disconnected.
In case of pool, closing connection means that connection is returned to pool.
First, I like to know why you want to close connection in the code mentioned?
When you close a session hibernate makes sure that it does not hold any reference to the connection. In Hibernate 3.6.8, the call is delegated to the ConnectionManager. Check closeConnection() method. In Hibernate 4 when you call session.connection() what you get is a proxy and in hibernate 3, you are most likely get wrapper over connection, if connection pool is configured.
So your option is to debug session.connection() and session.close(), and decide whether you want to close the coneection or not.With the kind of information you provided, any answer here will be pure assumption.
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.