public void clean() {
   Thread t = Thread.currentThread();
   threadMap.get(t);
   ConnectionHolder c = threadMap.get(t);
   if (c != null) {
     c.close();
     threadMap.remove(t);
   }
 }
 public Connection get() {
   if (closing) {
     return null;
   }
   Thread t = Thread.currentThread();
   ConnectionHolder ch = threadMap.get(t);
   if (ch != null) {
     return ch.get();
   }
   return null;
 }
 /**
  * Determine whether the given two Connections are equal, asking the target Connection in case of
  * a proxy. Used to detect equality even if the user passed in a raw target Connection while the
  * held one is a proxy.
  *
  * @param conHolder the ConnectionHolder for the held Connection (potentially a proxy)
  * @param passedInCon the Connection passed-in by the user (potentially a target Connection
  *     without proxy)
  * @return whether the given Connections are equal
  * @see #getTargetConnection
  */
 private static boolean connectionEquals(ConnectionHolder conHolder, Connection passedInCon) {
   if (!conHolder.hasConnection()) {
     return false;
   }
   Connection heldCon = conHolder.getConnection();
   // Explicitly check for identity too: for Connection handles that do not implement
   // "equals" properly, such as the ones Commons DBCP exposes).
   return (heldCon == passedInCon
       || heldCon.equals(passedInCon)
       || getTargetConnection(heldCon).equals(passedInCon));
 }
 public void set(Connection connection) {
   if (closing) {
     throw new IllegalStateException("ConnectionManager is closing ");
   }
   cleanThreadMap();
   Thread t = Thread.currentThread();
   ConnectionHolder c = threadMap.get(t);
   if (c != null) {
     c.close();
     threadMap.remove(t);
   }
   ConnectionHolder ch = new ConnectionHolder(connection, jdbcStorageClientPool);
   threadMap.put(t, ch);
 }
 /**
  * Apply the specified timeout - overridden by the current transaction timeout, if any - to the
  * given JDBC Statement object.
  *
  * @param stmt the JDBC Statement object
  * @param dataSource the DataSource that the Connection was obtained from
  * @param timeout the timeout to apply (or 0 for no timeout outside of a transaction)
  * @throws SQLException if thrown by JDBC methods
  * @see java.sql.Statement#setQueryTimeout
  */
 public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout)
     throws SQLException {
   Assert.notNull(stmt, "No Statement specified");
   Assert.notNull(dataSource, "No DataSource specified");
   ConnectionHolder holder =
       (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
   if (holder != null && holder.hasTimeout()) {
     // Remaining transaction timeout overrides specified value.
     stmt.setQueryTimeout(holder.getTimeToLiveInSeconds());
   } else if (timeout > 0) {
     // No current transaction timeout -> apply specified value.
     stmt.setQueryTimeout(timeout);
   }
 }
  public void close() {
    closing = true;
    while (threadMap.size() > 0) {

      Thread[] copy = threadMap.keySet().toArray(new Thread[threadMap.size()]);
      for (Thread t : copy) {
        ConnectionHolder ch = threadMap.remove(t);
        if (ch != null) {
          ch.close();
        }
      }
    }
    threadMap.clear();
    threadMap = null;
  }
 private void cleanThreadMap() {
   if (closing) {
     return;
   }
   Thread[] copy = threadMap.keySet().toArray(new Thread[threadMap.size()]);
   for (Thread t : copy) {
     if (!t.isAlive()) {
       ConnectionHolder ch = threadMap.remove(t);
       if (ch != null) {
         ch.close();
       }
     } else {
       ConnectionHolder ch = threadMap.get(t);
       if (ch != null && ch.hasExpired()) {
         ch = threadMap.remove(t);
         if (ch != null) {
           ch.close();
         }
       }
     }
   }
 }
  /**
   * Actually close the given Connection, obtained from the given DataSource. Same as {@link
   * #releaseConnection}, but throwing the original SQLException.
   *
   * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
   *
   * @param con the Connection to close if necessary (if this is <code>null</code>, the call will be
   *     ignored)
   * @param dataSource the DataSource that the Connection was obtained from (may be <code>null
   *     </code>)
   * @throws SQLException if thrown by JDBC methods
   * @see #doGetConnection
   */
  public static void doReleaseConnection(Connection con, DataSource dataSource)
      throws SQLException {
    if (con == null) {
      return;
    }

    if (dataSource != null) {
      ConnectionHolder conHolder =
          (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
      if (conHolder != null && connectionEquals(conHolder, con)) {
        // It's the transactional Connection: Don't close it.
        conHolder.released();
        return;
      }
    }

    // Leave the Connection open only if the DataSource is our
    // special SmartDataSoruce and it wants the Connection left open.
    if (!(dataSource instanceof SmartDataSource)
        || ((SmartDataSource) dataSource).shouldClose(con)) {
      logger.debug("Returning JDBC Connection to DataSource");
      con.close();
    }
  }
  /**
   * Actually obtain a JDBC Connection from the given DataSource. Same as {@link #getConnection},
   * but throwing the original SQLException.
   *
   * <p>Is aware of a corresponding Connection bound to the current thread, for example when using
   * {@link DataSourceTransactionManager}. Will bind a Connection to the thread if transaction
   * synchronization is active (e.g. if in a JTA transaction).
   *
   * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
   *
   * @param dataSource the DataSource to obtain Connections from
   * @return a JDBC Connection from the given DataSource
   * @throws SQLException if thrown by JDBC methods
   * @see #doReleaseConnection
   */
  public static Connection doGetConnection(DataSource dataSource) throws SQLException {
    Assert.notNull(dataSource, "No DataSource specified");

    ConnectionHolder conHolder =
        (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
    if (conHolder != null
        && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
      conHolder.requested();
      if (!conHolder.hasConnection()) {
        logger.debug("Fetching resumed JDBC Connection from DataSource");
        conHolder.setConnection(dataSource.getConnection());
      }
      return conHolder.getConnection();
    }
    // Else we either got no holder or an empty thread-bound holder here.

    logger.debug("Fetching JDBC Connection from DataSource");
    Connection con = dataSource.getConnection();

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
      logger.debug("Registering transaction synchronization for JDBC Connection");
      // Use same Connection for further JDBC actions within the transaction.
      // Thread-bound object will get removed by synchronization at transaction completion.
      ConnectionHolder holderToUse = conHolder;
      if (holderToUse == null) {
        holderToUse = new ConnectionHolder(con);
      } else {
        holderToUse.setConnection(con);
      }
      holderToUse.requested();
      TransactionSynchronizationManager.registerSynchronization(
          new ConnectionSynchronization(holderToUse, dataSource));
      holderToUse.setSynchronizedWithTransaction(true);
      if (holderToUse != conHolder) {
        TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
      }
    }

    return con;
  }