Tomcat Connection Pool abandoned issue - java

I'm struggling with a Tomcat connection pool error.The below error is thrown at runtime after running a simple stored procedure that generates a String value.
WARNING: Connection has been abandoned PooledConnection[ConnectionID:45 ClientConnectionId: 7817280c-3f7e-4239-a009-3aedd0a855e8]:java.lang.Exception
at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1096)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:799)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:648)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:200)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
at util.ThreadLocalUtil.getConnection(ThreadLocalUtil.java:55)
at webapp.dao.WebApplicationDAO.getConnection(WebApplicationDAO.java:30)
at webapp.dao.AccountDAO.generateAccountId(AccountDAO.java:827)
at webapp.bo.Account.generateUserAccountId(Account.java:285)
at webapp.actions.AddUserAccountUNZAction.execute(AddUserAccountUNZAction.java:79)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
My knowledge of that error is that a connection was opened and not closed. The connection is opened when running the stored proc in the account dao. Below is the block of code which calls the stored procedure.
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
stmt = conn.prepareCall(sqlWebAppGenerateUserId);
stmt.setString(1, base);
rs = stmt.executeQuery();
String res = null;
if (rs.next()) {
res = rs.getString(1);
}
if (res == null) {
throw new RuntimeException("Failed to generate user id.");
}
return res;
} catch (SQLException e) {
LOG.error("{}", e);
throw new RuntimeException(e);
}finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
LOG.error(e.getMessage(), e);
}
}
if (rs != null) {
try {
rs.close();
conn.close();
} catch (SQLException e) {
LOG.error(e.getMessage(), e);
}
}
}
As you can see, I'm using a finally block to close the connection etc.
I'm at a loss to explain the reason why the error is being thrown still and as to how I can debug and solve this issue. Any help would be greatly appreciated

You close conn only if rs != null, meaning that every time a query fails the connection won't be closed.
I also recommend switching to try-with-resources instead of writing clumsy finally blocks which may cause bugs.

What #Kayaman said. Also if the statement execution takes longer than removeAbandonedTimeout this can happen.

#Kayaman and #Gorazd thank you for the advice. The issue with down to missing jar files in the tomcat lib folder. More specifically mail-1.4.jar.
As this jar file was missing, a function that sends emails failed. Previous to the call to send the mail, connection.autocommit is set to true. After the mail sends it will set autocommit back to false. This to me looks like where the abandoned error was occurring from.
When looking through logs file I found the mail sending error. This was in actual fact the true error whereas the abandoned error can be looked at as a red herring.

Related

Resource management in bluemix and explicit closure of prepared statements in JDBC [duplicate]

It is said to be a good habit to close all JDBC resources after usage. But if I have the following code, is it necessary to close the Resultset and the Statement?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
The question is if the closing of the connection does the job or if it leaves some resources in use.
What you have done is perfect and very good practice.
The reason I say its good practice... For example, if for some reason you are using a "primitive" type of database pooling and you call connection.close(), the connection will be returned to the pool and the ResultSet/Statement will never be closed and then you will run into many different new problems!
So you can't always count on connection.close() to clean up.
Java 1.7 makes our lives much easier thanks to the try-with-resources statement.
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
try (ResultSet resultSet = statement.executeQuery("some query")) {
// Do stuff with the result set.
}
try (ResultSet resultSet = statement.executeQuery("some query")) {
// Do more stuff with the second result set.
}
}
This syntax is quite brief and elegant. And connection will indeed be closed even when the statement couldn't be created.
From the javadocs:
When a Statement object is closed, its
current ResultSet object, if one
exists, is also closed.
However, the javadocs are not very clear on whether the Statement and ResultSet are closed when you close the underlying Connection. They simply state that closing a Connection:
Releases this Connection object's
database and JDBC resources
immediately instead of waiting for
them to be automatically released.
In my opinion, always explicitly close ResultSets, Statements and Connections when you are finished with them as the implementation of close could vary between database drivers.
You can save yourself a lot of boiler-plate code by using methods such as closeQuietly in DBUtils from Apache.
I'm now using Oracle with Java. Here my point of view :
You should close ResultSet and Statement explicitly because Oracle has problems previously with keeping the cursors open even after closing the connection. If you don't close the ResultSet (cursor) it will throw an error like Maximum open cursors exceeded.
I think you may encounter with the same problem with other databases you use.
Here is tutorial Close ResultSet when finished:
Close ResultSet when finished
Close ResultSet object as soon as you finish
working with ResultSet object even
though Statement object closes the
ResultSet object implicitly when it
closes, closing ResultSet explicitly
gives chance to garbage collector to
recollect memory as early as possible
because ResultSet object may occupy
lot of memory depending on query.
ResultSet.close();
If you want more compact code, I suggest using Apache Commons DbUtils. In this case:
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(conn);
}
No you are not required to close anything BUT the connection. Per JDBC specs closing any higher object will automatically close lower objects. Closing Connection will close any Statements that connection has created. Closing any Statement will close all ResultSets that were created by that Statement. Doesn't matter if Connection is poolable or not. Even poolable connection has to clean before returning to the pool.
Of course you might have long nested loops on the Connection creating lots of statements, then closing them is appropriate. I almost never close ResultSet though, seems excessive when closing Statement or Connection WILL close them.
Doesn't matter if Connection is poolable or not. Even poolable connection has to clean before returning to the pool.
"Clean" usually means closing resultsets & rolling back any pending transactions but not closing the connection. Otherwise pooling looses its sense.
The correct and safe method for close the resources associated with JDBC this (taken from How to Close JDBC Resources Properly – Every Time):
Connection connection = dataSource.getConnection();
try {
Statement statement = connection.createStatement();
try {
ResultSet resultSet = statement.executeQuery("some query");
try {
// Do stuff with the result set.
} finally {
resultSet.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}
I created the following Method to create reusable One Liner:
public void oneMethodToCloseThemAll(ResultSet resultSet, Statement statement, Connection connection) {
if (resultSet != null) {
try {
if (!resultSet.isClosed()) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
if (!statement.isClosed()) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
if (!connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I use this Code in a parent Class thats inherited to all my classes that send DB Queries. I can use the Oneliner on all Queries, even if i do not have a resultSet.The Method takes care of closing the ResultSet, Statement, Connection in the correct order. This is what my finally block looks like.
finally {
oneMethodToCloseThemAll(resultSet, preStatement, sqlConnection);
}
With Java 6 form I think is better to check it is closed or not before close (for example if some connection pooler evict the connection in other thread) - for example some network problem - the statement and resultset state can be come closed. (it is not often happens, but I had this problem with Oracle and DBCP). My pattern is for that (in older Java syntax) is:
try {
//...
return resp;
} finally {
if (rs != null && !rs.isClosed()) {
try {
rs.close();
} catch (Exception e2) {
log.warn("Cannot close resultset: " + e2.getMessage());
}
}
if (stmt != null && !stmt.isClosed()) {
try {
stmt.close();
} catch (Exception e2) {
log.warn("Cannot close statement " + e2.getMessage());
}
}
if (con != null && !conn.isClosed()) {
try {
con.close();
} catch (Exception e2) {
log.warn("Cannot close connection: " + e2.getMessage());
}
}
}
In theory it is not 100% perfect because between the the checking the close state and the close itself there is a little room for the change for state. In the worst case you will get a warning in long. - but it is lesser than the possibility of state change in long run queries. We are using this pattern in production with an "avarage" load (150 simultanous user) and we had no problem with it - so never see that warning message.
Some convenience functions:
public static void silentCloseResultSets(Statement st) {
try {
while (!(!st.getMoreResults() && (st.getUpdateCount() == -1))) {}
} catch (SQLException ignore) {}
}
public static void silentCloseResultSets(Statement ...statements) {
for (Statement st: statements) silentCloseResultSets(st);
}
As far as I remember, in the current JDBC, Resultsets and statements implement the AutoCloseable interface. That means they are closed automatically upon being destroyed or going out of scope.

maximum open cursors exceeded exception in java code

this my code to execute update query
public boolean executeQuery(Connection con,String query) throws SQLException
{
boolean flag=false;
try
{
Statement st = con.createStatement();
flag=st.execute(query);
st.close();
st=null;
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;
}
maximum open cursor is set to 4000
code is executing
update tableA set colA ='x',lst_upd_date = trunc(sysdate) where trunc(date) = to_date('"+date+"','dd-mm-yyyy')
update query for around 8000 times
but after around 2000 days its throwing exception as "maximum open cursors exceeded"
please suggest code changes for this.
#TimBiegeleisen here is the code get connecttion
public Connection getConnection(String sessId)
{
Connection connection=null;
setLastAccessed(System.currentTimeMillis());
connection=(Connection)sessionCon.get(sessId);
try
{
if(connection==null || connection.isClosed() )
{
if ( ds == null )
{
InitialContext ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/iislDB");
}
connection=ds.getConnection();
sessionCon.put(sessId, connection);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return connection;
}
`
error stack is as bellow
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oopen.receive(Oopen.java:118)
at oracle.jdbc.ttc7.TTC7Protocol.open(TTC7Protocol.java:472)
at oracle.jdbc.driver.OracleStatement.<init>(OracleStatement.java:499)
at oracle.jdbc.driver.OracleConnection.privateCreateStatement(OracleConnection.java:683)
at oracle.jdbc.driver.OracleConnection.createStatement(OracleConnection.java:560)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.createStatement(DelegatingConnection.java:257)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.createStatement(PoolingDataSource.java:216)
at com.iisl.business.adminbo.computeindex.MoviIndexComputeBO.calculateMoviValue(MoviIndexComputeBO.java:230)
Your code has a cursor leak. That's what is causing the error. It seems unlikely that your code can really go 2000 days (about 5.5 years) before encountering the error. If that was the case, I'd wager that you'd be more than happy to restart a server twice a decade.
In your try block, you create a Statement. If an exception is thrown between the time that the statement is created and the time that st.close() is called, your code will leave the statement open and you will have leaked a cursor. Once a session has leaked 4000 cursors, you'll get the error. Increasing max_open_cursors will merely delay when the error occurs, it won't fix the underlying problem.
The underlying problem is that your try/ catch block needs a finally that closes the Statement if it was left open by the try. For this to work, you'd need to declare st outside of the try
finally {
if (st != null) {
st.close();
}
}
As mentioned in another response you will leak cursors if an exception is thrown during the statement execution because st.close() won't be executed. You can use Java's try-with-resources syntax to be sure that your statement object is closed:
try (Statement st = con.createStatement())
{
flag=st.execute(query);
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;
One of quickest solution is to increase cursor that each connection can handle by issuing following command on SQL prompt:
alter system set open_cursors = 1000
Also, add finally block in your code and close the connection to help closing cursors when ever exception occurs.
Also, run this query to see where actually cursor are opened.
select sid ,sql_text, count(*) as "OPEN CURSORS", USER_NAME from v$open_cursor
finally {
if (connection!=null) {
connection.close();
}

Error: Data source rejected establishment of connection, message from server: "Too many connections"

I created an application that writes data to the database every 5 minutes.
However after some time this error appears:
Error: Data source rejected establishment of connection, message from server: "Too many connections"
I've been searching around and tells you to close the connection to the database after every request side.
I tried this:
conexao.close();
But it gives me this error:
No operations allowed after conection closed.
I apologize if the question is not well formulated.
Thanks for the help
---------------------What I tried but didn't work---------------------------
Add
finally{
if(conexao!=null)
conexao.close();
}
Class.forName("com.mysql.jdbc.Driver");
Connection conexao = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/bdTeste", "root", "root");
Statement stm = conexao.createStatement();
BufferedReader reader = new BufferedReader(new FileReader("C:/Users/RPR1BRG/Desktop/test.txt"));
String dados[] = new String[6];
String linha = reader.readLine();
while (linha != null) {
StringTokenizer st = new StringTokenizer(linha, ";\"");
dados[0] = st.nextToken();
dados[1] = st.nextToken();
dados[2] = st.nextToken();
dados[3] = st.nextToken();
dados[4] = st.nextToken();
dados[5] = st.nextToken();
DateFormat dateFormat = new SimpleDateFormat("d-M-yy");
PreparedStatement stmt = (PreparedStatement) conexao.prepareStatement("replace into registos"
+ " (data_registo, hora_registo, IdSensor, Temperatura, Humidade, pt_orvalho) values (?,?,?,?,?,?)");
try {
stmt.setDate(1, new java.sql.Date(dateFormat.parse(dados[0]).getTime()));
stmt.setString(2, dados[1]);
stmt.setString(3, dados[2]);
stmt.setString(4, dados[3]);
stmt.setString(5, dados[4]);
stmt.setString(6, dados[5]);
} catch (java.text.ParseException ex) {
Exceptions.printStackTrace(ex);
}
stmt.executeUpdate();
linha = reader.readLine();
PrintWriter writer = new PrintWriter("C:/Users/RPR1BRG/Desktop/test.txt");
writer.print("");
writer.close();
Verifica();
}
} catch (ClassNotFoundException | SQLException | IOException e) {
System.err.println("Erro: " + e.getMessage());
}finally{
if(conexao!=null)
conexao.close();
}
This kind of problem arises when you are NOT properly closing the connection after usage.
Please use finally block after catch to close the connections appropriately. This is because to ensure that the connection gets closed properly even when there is an unexpected exception or error. Please note that statements inside finally block gets executed always. it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
As you have asked in comment, I have added the code sample to demonstrate practically!
Connection con = null
try{
//Establishing connection to datasource
con = DBConnection.getConnection();
//perform DB operations
...
...
...
}catch(SQLException sqlEx){
/*To catch any SQLException thrown during DB
*Operations and continue processing like sending alert to admin
*that exception occurred.
*/
}finally{
/*This block should be added to your code
* You need to release the resources like connections
*/
if(con!=null)
con.close();
}
Please note that the declaration of Connection variable should be in proper scope to close it in finally block.
Hope this helps!
This may be because of the configured max_connections is not suitable with the Connection Pool size set in JDBC or number of connections you open against DB.
to check number of max_connections in mysql:
show variables like 'max_connections';
make sure you have proper value of opened connections with the DB Max connections.
As from Java 7, java.sql.Connection is AutoCloseable. From now on, you can write your code like this:
try(Connection con = (Connection) DriverManager.getConnection(url, username, pazzword)) {
//your statements
}catch(RuntimeException e) {
}
Restart apache tomcat server will work. This worked for me.
Welcome

automatic closing of result-set in Java SQL

Consider the following code
ResultSet rs = null;
Statement st = null;
try {
//do somehting
} catch (Exception e){
//do something
} finally {
if(st != null){
try {
st.close();
} catch (SQLException e) {
log.error("Exception while closing statement: " + e);
}
}
}
The question is that when we close the statement, will it close the result set as well or do we need to explicitly close the result set like this
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
log.error("Exception while closing result set: " + e);
}
}
I thought that closing the statement will automatically close the result set, but FindBugs throws the following warning if I don't explicitly close the result set
This method may fail to clean up java.sql.ResultSet
When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
This and this shows that Oracle may have problems and you might have to explicitly close the ResultSet. But again, as per the Javadocs, this shouldn't be an issue. Hence, the warning,maybe.
You can't count on the ResultSet being closed automatically, it depends on the driver implementation and how compliant it is. The best policy is to close the ResultSet explicitly.
When you close the statement or connection, all it's children should be closed too by default.

Java 7 Automatic Resource Management JDBC (try-with-resources statement)

How to integrate the common JDBC idiom of creating/receiving a connection, querying the database and possibly processing the results with Java 7's automatic resource management, the try-with-resources statement? (Tutorial)
Before Java 7, the usual pattern was something like this:
Connection con = null;
PreparedStatement prep = null;
try{
con = getConnection();
prep = prep.prepareStatement("Update ...");
...
con.commit();
}
catch (SQLException e){
con.rollback();
throw e;
}
finally{
if (prep != null)
prep.close();
if (con != null)
con.close();
}
With Java 7 you can go for:
try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){
...
con.commit();
}
This will close the Connection and the PreparedStatement, but what about the rollback? I cannot add a catch clause containing the rollback, because the connection is only available within the try block.
Do you still define the connection outside of the try block? What is the best practice here, especially if connection pooling is used?
try(Connection con = getConnection()) {
try (PreparedStatement prep = con.prepareConnection("Update ...")) {
//prep.doSomething();
//...
//etc
con.commit();
} catch (SQLException e) {
//any other actions necessary on failure
con.rollback();
//consider a re-throw, throwing a wrapping exception, etc
}
}
According to the oracle documentation, you can combine a try-with-resources block with a regular try block. IMO, the above example captures the correct logic, which is:
Attempt to close the PreparedStatement if nothing goes wrong
If something goes wrong in the inner block, (no matter what is is) roll back the current transaction
Attempt to close the connection no matter what
If something goes wrong closing the connection, you can't rollback the transaction (as that's a method on the connection, which is now in indeterminate state), so don't try
In java 6 and earlier, I would do this with a triply nested set of try blocks (outer try-finally, middle try-catch, inner try-finally). ARM syntax does make this terser.
IMO, declaring Connection and PreparedStatement outside try-catch is the best way available in this case.
If you want to use pooled connection in transaction, you should use it in this way:
try (Connection conn = source.getConnection()) {
conn.setAutoCommit(false);
SQLException savedException = null;
try {
// Do things with connection in transaction here...
conn.commit();
} catch (SQLException ex) {
savedException = ex;
conn.rollback();
} finally {
conn.setAutoCommit(true);
if(savedException != null) {
throw savedException;
}
}
} catch (SQLException ex1) {
throw new DataManagerException(ex1);
}
This sample code handles setting autocommit values.
NOTE, that using savedException does save exception in case that conn.rollback() throws another. This way, finally block will throw "right" exception.

Categories

Resources