package in.partake.model.dao; import java.util.Date; import play.Logger; public abstract class PartakeConnectionPool { // 同じ thread が複数の connection を取ると deadlock の可能性がある。その場合には警告されるため、修正すること。 private ThreadLocal<Integer> numAcquiredConnection; private ThreadLocal<String> firstConnectionName; protected PartakeConnectionPool() { this.numAcquiredConnection = new ThreadLocal<Integer>(); this.firstConnectionName = new ThreadLocal<String>(); } public int getCurrentNumberOfConnectionForThisThread() { Integer numConnection = numAcquiredConnection.get(); if (numConnection == null) return 0; else return numConnection; } /** Connection を得る */ public final PartakeConnection getConnection() throws DAOException { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); String name = "unknown"; if (stackTrace != null && stackTrace.length > 3) { name = stackTrace[3].getClassName() + "#" + stackTrace[3].getMethodName(); } if (numAcquiredConnection.get() == null) { numAcquiredConnection.set(new Integer(1)); } else { numAcquiredConnection.set(numAcquiredConnection.get() + 1); } if (numAcquiredConnection.get() > 1) { Logger.warn(name + " : The same thread has taken multiple connections. This may cause a bug. "); if (firstConnectionName.get() != null) { Logger.warn(firstConnectionName.get() + " is the first connection."); } } if (firstConnectionName.get() == null) { firstConnectionName.set(name); } Logger.debug("borrowing... " + name + " : " + numAcquiredConnection.get()); return getConnectionImpl(name); } protected abstract PartakeConnection getConnectionImpl(String name) throws DAOException; /** Connection を返す */ public final void releaseConnection(PartakeConnection connection) { int tenSeconds = 1000 * 10; Date now = new Date(); if (connection.getAcquiredTime() + tenSeconds < now.getTime()) { Logger.warn("connection [" + connection.getName() + "] have been acquired for " + (now.getTime() - connection.getAcquiredTime()) + " milliseconds."); } numAcquiredConnection.set(numAcquiredConnection.get() - 1); if (numAcquiredConnection.get() == 0) { firstConnectionName.set(null); } Logger.debug("releasing... " + connection.getName() + " : " + numAcquiredConnection.get()); releaseConnectionImpl(connection); } protected abstract void releaseConnectionImpl(PartakeConnection connection); /** この Connection Pool が不要になる直前に呼ばれる。必要に応じてコネクションプールを解放する。*/ public abstract void willDestroy(); }