r2244 - trunk/topia-persistence/src/main/java/org/nuiton/topia/framework
Author: tchemit Date: 2011-04-14 14:46:27 +0200 (Thu, 14 Apr 2011) New Revision: 2244 Url: http://nuiton.org/repositories/revision/topia/2244 Log: Improve code Add javadoc Add license headers (svn keywords...) Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaConnectionProvider.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaConnectionProvider.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaConnectionProvider.java 2011-04-14 11:15:26 UTC (rev 2243) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaConnectionProvider.java 2011-04-14 12:46:27 UTC (rev 2244) @@ -1,3 +1,27 @@ +/* + * #%L + * ToPIA :: Persistence + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ package org.nuiton.topia.framework; import org.apache.commons.logging.Log; @@ -19,30 +43,75 @@ /** * Customized connection provider. + * <p/> + * This provider fix the following bug : + * http://nuiton.org/issues/show/561 + * <p/> + * To use this connection provider, add this property to topia configuration + * <p/> + * <pre> + * config.setProperty(Environment.CONNECTION_PROVIDER, TopiaConnectionProvider.class.getName()); + * </pre> + * <p/> + * or in a properties file : + * <p/> + * <pre> + * hibernate.connection.provider_class=org.nuiton.topia.framework.TopiaConnectionProvider + * </pre> * * @author tchemit <chemit@codelutin.com> * @since 2.5.3 */ public class TopiaConnectionProvider implements ConnectionProvider { + /** Logger. */ + private static final Log log = + LogFactory.getLog(TopiaConnectionProvider.class); + + /** + * JDBC url of connection. + * <p/> + * This is a mandatory hibernate configuration vi the property + * {@link Environment#URL}. + */ private String url; + /** All grabbed connection properties */ private Properties connectionProps; + /** + * Sql isolation level to use in connection. + * <p/> + * Can be configured by hibernate property {@link Environment#ISOLATION_LEVELS}. + * + * @see Connection#getTransactionIsolation() + */ private Integer isolation; - private final List<Connection> pool = new ArrayList<Connection>(); + /** + * auto commit connection state. + * <p/> + * Can be configured by hibernate property {@link Environment#AUTOCOMMIT}. + * + * @see Connection#getAutoCommit() + */ + private boolean autocommit; + /** + * Size of connection pool. + * <p/> + * By default use {@code 20}, can be specify by using the hibernate + * configuration property {@link Environment#POOL_SIZE}. + */ private int poolSize; - private int checkedOut; + /** Our pool of connections which are not closed and availables. */ + private final List<Connection> pool; - private boolean autocommit; + public TopiaConnectionProvider() { + pool = new ArrayList<Connection>(); + } - /** Logger. */ - private static final Log log = - LogFactory.getLog(TopiaConnectionProvider.class); - @Override public void configure(Properties props) throws HibernateException { String driverClass = props.getProperty(Environment.DRIVER); @@ -114,11 +183,8 @@ @Override public Connection getConnection() throws SQLException { - if (log.isTraceEnabled()) { - log.trace("total checked-out connections: " + checkedOut); - } - // always clean the pool before any use of it + Connection connection = null; synchronized (pool) { @@ -127,8 +193,8 @@ Iterator<?> itr = pool.iterator(); while (itr.hasNext()) { - Connection connection = (Connection) itr.next(); - if (connection.isClosed()) { + Connection conn = (Connection) itr.next(); + if (conn.isClosed()) { // this connection is closed!, remove it itr.remove(); @@ -139,73 +205,74 @@ } } } + + // try to use a connection from the pool (if any) + if (!pool.isEmpty()) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); - checkedOut++; } - Connection pooled = pool.remove(last); - if (isolation != null) { - pooled.setTransactionIsolation(isolation); - } - if (pooled.getAutoCommit() != autocommit) - pooled.setAutoCommit(autocommit); - return pooled; + + connection = pool.remove(last); } } - log.debug("opening new JDBC connection"); - Connection conn = DriverManager.getConnection(url, connectionProps); - if (isolation != null) { - conn.setTransactionIsolation(isolation); + if (connection == null) { + + // the pool was empty, creates a new connection + + if (log.isDebugEnabled()) { + log.debug("opening new JDBC connection to " + url); + } + connection = DriverManager.getConnection(url, connectionProps); } - if (conn.getAutoCommit() != autocommit) { - conn.setAutoCommit(autocommit); - } - if (log.isDebugEnabled()) { - log.debug("created connection to: " + url + ", Isolation Level: " + - conn.getTransactionIsolation()); + // configure connection + + if (isolation != null) { + connection.setTransactionIsolation(isolation); } - if (log.isTraceEnabled()) { - checkedOut++; + if (connection.getAutoCommit() != autocommit) { + connection.setAutoCommit(autocommit); } - return conn; + return connection; } @Override public void closeConnection(Connection conn) throws SQLException { + // if connection is already closed, nothing has to be done + // we can't keep this connection (and can not be push in pool) + if (conn.isClosed()) { - // if connection already closed (I don't know how, make sure it is - // not any longer used by pool) if (log.isDebugEnabled()) { log.debug("Connection [" + conn + "] alreay closed!, will not use it any longer "); } return; } - if (log.isDebugEnabled()) { - checkedOut--; - } + // connection was not closed, can push it in the pool (if pool is not + // full) + synchronized (pool) { int currentSize = pool.size(); - if (currentSize < poolSize) { + if (currentSize < getPoolSize()) { if (log.isTraceEnabled()) { log.trace("returning connection to pool, pool size: " + (currentSize + 1)); } - pool.add(conn); return; } } + // pool was full, must release the connection which will be loose + if (log.isDebugEnabled()) { log.debug("closing JDBC connection"); } @@ -219,6 +286,7 @@ close(); } + @Override public void close() { if (log.isInfoEnabled()) { @@ -242,4 +310,29 @@ public boolean supportsAggressiveRelease() { return false; } + + public String getUrl() { + return url; + } + + public Properties getConnectionProps() { + return connectionProps; + } + + public Integer getIsolation() { + return isolation; + } + + public List<Connection> getPool() { + return pool; + } + + public int getPoolSize() { + return poolSize; + } + + public boolean isAutocommit() { + return autocommit; + } + } Property changes on: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaConnectionProvider.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL
participants (1)
-
tchemit@users.nuiton.org