Connection is not released - Lock owned during cleanup - Using Java Callables
vanecan Mar 23, 2015 4:52 PMUsing jdbc driver: pgjdbc-ng 0.3 -- impossibl/pgjdbc-ng · GitHub
Using Threads.
I'm using threads because i need to call 3 store procedures at the same time.
I cannot wait the process and do it sequentially because it will cost to much time.
## How I got my connection?
The param jndi is parametrized and is correct.
DataSource dataSource = InitialContext.doLookup(jndi);
This datasource is stored in memory during the application life, it means all the time.
When I need a connection I do:
Connection conn = dataSource.getConnection(); conn.setTypeMap(map);
## How I used the connection?
I have a class ConciliadorCallable that implements Callable interface, it is like a thread but it can return something.
I override the call() method like this:
public RetornoType call() { String ident = "[Thread:" + routine + " : " + id + " : " + msisdn + "]"; log.info(ident); CallableStatement cs = null; Connection unwrapedConnection = null; RetornoType r = null; try { unwrapedConnection = controller.getConnection(); String sql = "{ call " + routine + "(?,???) }"; log.info(ident + ": Ejecutando: " + sql); cs = unwrapedConnection.prepareCall(sql); cs.setInt(1, id); cs.setString(2, msisdn); cs.registerOutParameter(3, Types.VARCHAR); cs.registerOutParameter(4, Types.VARCHAR); cs.execute(); String codigo = cs.getString(3); String mensaje = cs.getString(4); r = new RetornoType(codigo, mensaje); log.info(ident + ": Executed ok: " + codigo); } catch (MiddlewareCallException ex) { answer = new RetornoType("-1", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } catch (ParseException ex) { answer = new RetornoType("-2", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } catch (DatabaseConnectionException ex) { answer = new RetornoType("-3", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } catch (IllegalArgumentException ex) { answer = new RetornoType("-4", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } catch (IllegalAccessException ex) { answer = new RetornoType("-5", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } catch (SQLException ex) { answer = new RetornoType("-6", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); log.info(ex.getSQLState() + " : " + ex.getMessage()); } catch (Exception ex) { answer = new RetornoType("-7", ident + ex.getMessage()); log.error(ident + "\n" + answer, ex); } finally { try { log.info(ident + ": Finally."); if (cs != null && !cs.isClosed()) { cs.close(); log.info(ident + ": Callable statement closed."); } if (unwrapedConnection != null && !unwrapedConnection.isClosed()) { unwrapedConnection.close(); log.info(ident + ": Connection closed."); } } catch (SQLException ex) { log.info("Error closing connections."); log.error(ident, ex); } } return answer == null ? r : answer; }
And I use the "thread" like this:
ArrayList<ConciliadorCallable> tasks = new ArrayList<>(); tasks.add(new ConciliadorCallable("HLR", "conciliar", id, msisdn)); tasks.add(new ConciliadorCallable("HSS", "conciliar_hss", id, msisdn)); tasks.add(new ConciliadorCallable("PCRF", "conciliar_pcrf", id, msisdn)); ExecutorService pool = Executors.newFixedThreadPool(tasks.size()); HashMap<String, Future> set = new HashMap<>(); ArrayList<RespuestaConciliador> respuestas = new ArrayList<>(); for (ConciliadorCallable task : tasks) { Future<RetornoType> future = pool.submit(task); set.put(task.plataforma, future); } for (Entry<String, Future> future : set.entrySet()) { try { log.info("Obtaining answer from FutureTask: " + future.getKey()); respuestas.add(new RespuestaConciliador((RetornoType) future.getValue().get(), future.getKey())); } catch (InterruptedException | ExecutionException ex) { log.error("ERROR:", ex); respuestas.add(new RespuestaConciliador(new RetornoType("-9", ex.getMessage()), future.getKey())); } } pool.shutdown();
What's the problem?
When I call the service for the first time it works. But later in the second time it seems like the connections are never released. And I can't make it work.
I have to disable the datasource in the Jboss and enable it again.. But as is imaginable it works just one time again..
My connection pool had a max of 3 to prove my point that the connections are never "closed".
This is the warning I have when disable the datasource in Jboss..
12:14:03,953 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) JBAS010409: Fuente de datos desenlazados [java:jboss/datasources/PROVISIONING-POSTGRES]
12:14:03,959 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 251) IJ000615: Destroying active connection in pool: PROVISIONING-POSTGRES (org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@19ac2b9b)
12:14:03,960 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 251) IJ000615: Destroying active connection in pool: PROVISIONING-POSTGRES (org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@7662da47)
12:14:03,960 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 251) IJ000615: Destroying active connection in pool: PROVISIONING-POSTGRES (org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@53e8a809)
12:14:03,960 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 251) IJ000615: Destroying active connection in pool: PROVISIONING-POSTGRES (org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@4f7011e8)
12:14:03,960 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 251) IJ000615: Destroying active connection in pool: PROVISIONING-POSTGRES (org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@46a7bf16)
12:14:03,960 WARN [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (ServerService Thread Pool -- 251) Lock owned during cleanup: pool-92-thread-1: java.lang.Throwable: Lock owned during cleanup: pool-92-thread-1
at java.lang.Object.wait(Native Method) [rt.jar:1.7.0_45]
at com.impossibl.postgres.protocol.v30.CommandImpl.waitFor(CommandImpl.java:119)
at com.impossibl.postgres.protocol.v30.BindExecCommandImpl.execute(BindExecCommandImpl.java:346)
at com.impossibl.postgres.protocol.v30.ProtocolImpl.execute(ProtocolImpl.java:369)
at com.impossibl.postgres.jdbc.PGConnectionImpl.execute(PGConnectionImpl.java:428)
at com.impossibl.postgres.jdbc.PGStatement.executeStatement(PGStatement.java:372)
at com.impossibl.postgres.jdbc.PGPreparedStatement.execute(PGPreparedStatement.java:233)
at com.impossibl.postgres.jdbc.PGCallableStatement.execute(PGCallableStatement.java:145)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.execute(WrappedPreparedStatement.java:404) [ironjacamar-jdbc-1.0.26.Final-redhat-1.jar:1.0.26.Final-redhat-1]
at py.com.personal.is.provisioning.postgres.rest.conciliacion.ConciliadorCallable.llamar(ConciliadorCallable.java:86)
at py.com.personal.is.provisioning.postgres.rest.conciliacion.ConciliadorCallable.call(ConciliadorCallable.java:66)
at py.com.personal.is.provisioning.postgres.rest.conciliacion.ConciliadorCallable.call(ConciliadorCallable.java:31)
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_45]
at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]