Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014-2015 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  * either express or implied. See the License for the specific language
  * governing permissions and limitations under the License.
  */
 package org.lastaflute.jta.dbcp;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 

Author(s):
modified by jflute (originated in Seasar)
 
 public class SimpleConnectionPool implements ConnectionPool {
 
     // ===================================================================================
     //                                                                          Definition
     //                                                                          ==========
     private static final Logger logger = LoggerFactory.getLogger(SimpleConnectionPool.class);
 
     public static final String readOnly_BINDING = "bindingType=may";
     public static final String transactionIsolationLevel_BINDING = "bindingType=may";
     public static final int DEFAULT_TRANSACTION_ISOLATION_LEVEL = -1;
 
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           =========
     protected XADataSource xaDataSource;
     protected int timeout = 600; // timeout seconds until closing free connection
     protected int maxPoolSize = 10; // maximum count of pooled connection
     protected int minPoolSize = 0; // minimum count of pooled connection
 
     // change default value from -1 to the big value *extension
     // because unlimited gives us system ending without info if application bugs
     // failure with big value might mean application bugs
     // so want to output exception and to show error message to user
     protected long maxWait = 10000; // milliseconds of waiting for free connection (-1: unlimited, 0: no wait)
 
     protected boolean allowLocalTx = true// allow to check out in out of transaction?
     protected boolean readOnly = false;
     protected String validationQuery;
     protected long validationInterval;
     protected final Set<ConnectionWrapperactivePool = createActivePoolSet();
     protected final LjtLinkedList freePool = createFreePoolList();
     protected LjtTimeoutTask timeoutTask;
 
     protected Set<ConnectionWrappercreateActivePoolSet() {
         return new HashSet<ConnectionWrapper>();
     }
 
         return new HashMap<TransactionConnectionWrapper>();
     }
 
     protected LjtLinkedList createFreePoolList() {
        return new LjtLinkedList();
    }
    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    public SimpleConnectionPool() {
         = LjtTimeoutManager.getInstance().addTimeoutTarget(createTimeoutTarget(), .true);
    }
    protected LjtTimeoutTarget createTimeoutTarget() {
        return new LjtTimeoutTarget() {
            public void expired() {
            }
        };
    }
    // ===================================================================================
    //                                                                           Check Out
    //                                                                           =========
    public synchronized ConnectionWrapper checkOut() throws SQLException {
        final Transaction tx = getTransaction();
        if (tx == null && !isAllowLocalTx()) {
            throw new LjtIllegalStateException("Not begun transaction. (not allowed local transaction)");
        }
        ConnectionWrapper wrapper = getConnectionTxActivePool(tx);
        if (wrapper != null) {
            // TODO jflute lastaflute: [E] fitting: DI :: connection pool logical connection logging for internal debug
            //if (logger.isDebugEnabled()) {
            //    logger.debug("...Checking out logical connection from pool: {}", tx);
            //}
            return wrapper;
        }
        long wait = ;
        while (getMaxPoolSize() > 0 && getActivePoolSize() + getTxActivePoolSize() >= getMaxPoolSize()) {
            if (wait == 0L) {
                throwConnectionPoolShortFreeException(); // *extension
            }
            final long startTime = System.currentTimeMillis();
            try {
                wait(( == -1L) ? 0L : wait);
            } catch (InterruptedException e) {
                // TODO jflute lastaflute: [E] fitting: DI :: connection pool exception handling
                throw new LjtSQLException("Cannot wait the connection back to pool"e);
            }
            final long elapseTime = System.currentTimeMillis() - startTime;
            if (wait > 0L) {
                wait -= Math.min(waitelapseTime);
            }
        }
        wrapper = checkOutFreePool(tx);
        if (wrapper == null) {
            wrapper = createConnection(tx);
        }
        if (tx == null) {
            setConnectionActivePool(wrapper);
        } else {
            LjtTransactionUtil.enlistResource(txwrapper.getXAResource());
            LjtTransactionUtil.registerSynchronization(txcreateSynchronizationImpl(tx));
            setConnectionTxActivePool(txwrapper);
        }
        wrapper.setReadOnly();
            wrapper.setTransactionIsolation();
        }
        if (.isDebugEnabled()) {
            .debug("...Checking out logical connection from pool: {}"tx);
        }
        return wrapper;
    }
    protected Transaction getTransaction() {
        return LjtTransactionManagerUtil.getTransaction();
    }
        return (ConnectionWrapper.get(tx);
    }
        if (.isEmpty()) {
            return null;
        }
        final FreeItem item = (FreeItem.removeLast();
        final ConnectionWrapper wrapper = item.getConnection();
        wrapper.init(tx);
        item.destroy();
        if ( == null || .isEmpty()) {
            return wrapper;
        }
        if (validateConnection(wrapperitem.getPooledTime())) {
            return wrapper;
        }
        return null;
    }
    protected boolean validateConnection(ConnectionWrapper wrapperfinal long pooledTime) {
        final long currentTime = System.currentTimeMillis();
        if (currentTime - pooledTime < ) {
            return true;
        }
        try {
            final PreparedStatement ps = wrapper.prepareStatement();
            try {
                ps.executeQuery();
            } finally {
                ps.close();
            }
        } catch (final Exception e) {
            try {
                wrapper.close();
            } catch (final Exception ignore) {}
            for (LjtLinkedList.Entry entry = .getFirstEntry(); entry != nullentry = entry.getNext()) {
                final FreeItem item = (FreeItementry.getElement();
                try {
                    item.getConnection().closeReally();
                } catch (final Exception ignore) {}
            }
            .clear();
            .error("Destroyed the pooled connections because validation error: " + pooledTimee);
            return false;
        }
        return true;
    }
    protected ConnectionWrapper createConnection(Transaction txthrows SQLException {
        final XAConnection xaConn = .getXAConnection();
        final Connection conn = xaConn.getConnection();
        final ConnectionWrapper wrapper = createTransactionalConnectionWrapperImpl(xaConnconntx);
        if (.isDebugEnabled()) {
            .debug("Created physical connection: tx={}, conn={}"txconn);
        }
        return wrapper;
    }
            throws SQLException {
        return new ConnectionWrapperImpl(xaConnectionconnthistx);
    }
    protected void setConnectionActivePool(ConnectionWrapper connection) {
        .add(connection);
    }
        return new SynchronizationImpl(tx);
    }
    protected void setConnectionTxActivePool(Transaction txConnectionWrapper wrapper) {
        .put(txwrapper);
    }
    // ===================================================================================
    //                                                                             Release
    //                                                                             =======
    public synchronized void release(ConnectionWrapper connection) {
        .remove(connection);
        final Transaction tx = getTransaction();
        if (tx != null) {
            .remove(tx);
        }
        connection.closeReally();
        notify();
    }
    // ===================================================================================
    //                                                                            Check In
    //                                                                            ========
    public synchronized void checkIn(ConnectionWrapper wrapper) {
        .remove(wrapper);
        checkInFreePool(wrapper);
    }
    protected void checkInFreePool(ConnectionWrapper wrapper) {
        if (getMaxPoolSize() > 0) {
            try {
                final Connection pc = wrapper.getPhysicalConnection();
                pc.setAutoCommit(true);
                final ConnectionWrapper newCon = createInheritedConnectionWrapperImpl(wrapperpc);
                wrapper.cleanup();
                .addLast(new FreeItem(newCon));
                notify();
            } catch (SQLException e) {
                throw new LjtRuntimeException("Failed to check in the free pool: " + wrappere);
            }
        } else {
            wrapper.closeReally();
        }
    }
        return new ConnectionWrapperImpl(wrapper.getXAConnection(), pcthisnull);
    }
    public synchronized void checkInTx(Transaction tx) {
        if (tx == null) {
            return;
        }
        if (getTransaction() != null) {
            return;
        }
        final ConnectionWrapper wrapper = (ConnectionWrapper.remove(tx);
        if (wrapper == null) {
            return;
        }
        checkInFreePool(wrapper);
    }
    // ===================================================================================
    //                                                                               Close
    //                                                                               =====
    public final synchronized void close() {
        for (LjtLinkedList.Entry e = .getFirstEntry(); e != nulle = e.getNext()) {
            final FreeItem item = (FreeIteme.getElement();
            item.getConnection().closeReally();
            item.destroy();
        }
        .clear();
        for (Iterator<ConnectionWrapperi = .values().iterator(); i.hasNext();) {
            final ConnectionWrapper con = i.next();
            con.closeReally();
        }
        .clear();
        for (Iterator<ConnectionWrapperi = .iterator(); i.hasNext();) {
            final ConnectionWrapper con = i.next();
            con.closeReally();
        }
        .clear();
        .cancel();
    }
    protected class FreeItem implements LjtTimeoutTarget {
        protected ConnectionWrapper connectionWrapper_;
        protected LjtTimeoutTask timeoutTask_;
        protected long pooledTime// millisecond
        protected FreeItem(ConnectionWrapper connectionWrapper) {
             = connectionWrapper;
             = LjtTimeoutManager.getInstance().addTimeoutTarget(thisfalse);
             = System.currentTimeMillis();
        }
        public ConnectionWrapper getConnection() {
            return ;
        }
        public long getPooledTime() {
            return ;
        }
        public void expired() {
            synchronized (SimpleConnectionPool.this) {
                if (.size() <= ) {
                    return;
                }
                .remove(this);
            }
            synchronized (this) {
                if ( != null) {
                    .closeReally();
                     = null;
                }
            }
        }
        public synchronized void destroy() {
            if ( != null) {
                .cancel();
                 = null;
            }
             = null;
        }
    }

    

Author(s):
modified by jflute (originated in Seasar)
    public class SynchronizationImpl implements Synchronization {
        protected final Transaction tx;
        public SynchronizationImpl(final Transaction tx) {
            this. = tx;
        }
        public final void beforeCompletion() {
        }
        public void afterCompletion(final int status) {
            switch (status) {
            case .:
            case .:
                checkInTx();
                break;
            }
        }
    }
    // ===================================================================================
    //                                                                 Traceable Extension
    //                                                                 ===================
    protected void throwConnectionPoolShortFreeException() throws SQLException {
        final LjtExceptionMessageBuilder br = new LjtExceptionMessageBuilder();
        br.addNotice("Connection pool did not have a free connection.");
        br.addItem("Pool Settings");
        br.addElement("timeout: " + );
        br.addElement("maxPoolSize: " + );
        br.addElement("minPoolSize: " + );
        br.addElement("maxWait: " + );
        br.addItem("Plain ActivePool");
        br.addElement("size: " + .size());
        br.addItem("Transaction ActivePool");
        br.addElement("size: " + .size());
        final List<StringexpList = extractActiveTransactionExpList();
        for (String exp : expList) {
            br.addElement(exp);
        }
        final String msg = br.buildExceptionMessage();
        throw new ConnectionPoolShortFreeSQLException(msg);
    }
    public synchronized List<StringextractActiveTransactionExpList() {
        final List<StringexpList = new ArrayList<String>(.size());
        for (Entry<TransactionConnectionWrapperentry : .entrySet()) {
            final Transaction tx = entry.getKey();
            final ConnectionWrapper wrapper = entry.getValue();
            final String romantic = buildRomanticExp(txwrapper);
            expList.add(romantic);
        }
        return expList;
    }
    protected String buildRomanticExp(Transaction txConnectionWrapper wrapper) {
        return tx.toString();
    }
    // ===================================================================================
    //                                                                            Accessor
    //                                                                            ========
    public XADataSource getXADataSource() {
        return ;
    }
    public void setXADataSource(XADataSource xaDataSource) {
        this. = xaDataSource;
    }
        return ;
    }
    public void setTransactionManager(TransactionManager transactionManager) {
        this. = transactionManager;
    }
    public int getTimeout() {
        return ;
    }
    public void setTimeout(int timeout) {
        this. = timeout;
    }
    public int getMaxPoolSize() {
        return ;
    }
    public void setMaxPoolSize(int maxPoolSize) {
        this. = maxPoolSize;
    }
    public int getMinPoolSize() {
        return ;
    }
    public void setMinPoolSize(int minPoolSize) {
        this. = minPoolSize;
    }
    public long getMaxWait() {
        return ;
    }
    public void setMaxWait(long maxWait) {
        this. = maxWait;
    }
    public boolean isAllowLocalTx() {
        return ;
    }
    public void setAllowLocalTx(boolean allowLocalTx) {
        this. = allowLocalTx;
    }
    public boolean isReadOnly() {
        return ;
    }
    public void setReadOnly(boolean readOnly) {
        this. = readOnly;
    }
    public int getTransactionIsolationLevel() {
        return ;
    }
    public void setTransactionIsolationLevel(int transactionIsolationLevel) {
        this. = transactionIsolationLevel;
    }
    public String getValidationQuery() {
        return ;
    }
    public void setValidationQuery(String validationQuery) {
        this. = validationQuery;
    }
    public long getValidationInterval() {
        return ;
    }
    public void setValidationInterval(long validationInterval) {
        this. = validationInterval;
    }
    public int getActivePoolSize() {
        return .size();
    }
    public int getTxActivePoolSize() {
        return .size();
    }
    public int getFreePoolSize() {
        return .size();
    }
New to GrepCode? Check out our FAQ X