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; }