Author: bpoussin Date: 2011-04-29 20:22:17 +0200 (Fri, 29 Apr 2011) New Revision: 852 Url: http://nuiton.org/repositories/revision/wikitty/852 Log: Anomalie #1492: Refactor transaction management Added: trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyManagedDataSource.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyTransaction.java trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyExtensionStorageJDBC.java trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyJDBCUtil.java trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyStorageJDBC.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2011-04-29 18:22:17 UTC (rev 852) @@ -96,7 +96,7 @@ WIKITTY_STORAGE_JDBC_XADATASOURCE( "wikitty.storage.jdbc.xadatasource", n_("JDBC xadatasource driver"), - "org.h2.jdbcx.JdbcDataSource", + null, // no default XA otherwize we must set it to empty in all config file String.class, false, false), WIKITTY_STORAGE_JDBC_XADATASOURCE_H2_URL( "wikitty.storage.jdbc.xadatasource.org.h2.jdbcx.JdbcDataSource.URL", Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2011-04-29 18:22:17 UTC (rev 852) @@ -1178,7 +1178,7 @@ txBeginHere = true; } - boolean result = getWikittyStorage().exists(null, wikittyId); + boolean result = getWikittyStorage().exists(tx, wikittyId); if (txBeginHere) { tx.commit(); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyTransaction.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyTransaction.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyTransaction.java 2011-04-29 18:22:17 UTC (rev 852) @@ -24,8 +24,14 @@ */ package org.nuiton.wikitty.services; +import java.sql.Connection; +import java.sql.SQLException; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.transaction.Status; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; @@ -45,6 +51,8 @@ /** permet d'attacher n'importe quoi a une transaction */ protected Map<Object, Object> tagValues; + /** les connections a ferme apres un commit ou rollback */ + protected LinkedList<Connection> enlistedConnections = new LinkedList<Connection>(); /** if true begin has been called for this transaction */ protected boolean started = false; @@ -79,6 +87,13 @@ tagValues.put(tag, value); } + public void addEnlistedConnection(Connection enlistedConnection) { + if (!isStarted()) { + throw new WikittyException("You can't add connection in transaction when transaction is not begin"); + } + this.enlistedConnections.add(enlistedConnection); + } + public boolean isStarted() { return started; } @@ -122,6 +137,8 @@ setStarted(false); } catch (Exception eee) { throw new WikittyException("Error on commit JTA transaction", eee); + } finally { + close(); } } @@ -138,7 +155,43 @@ setStarted(false); } catch (Exception eee) { throw new WikittyException("Error on roolback JTA transaction", eee); + } finally { + close(); } } + + /** + * Close all enlisted connection, this method is automaticaly call after + * commit or rollback. + * + * A priori normalement cela devrait etre fait automatiquement par dbcp + * avec le commit/rollback mais ce n'est pas le cas + * {@link org.apache.commons.dbcp.managed.ManagedConnection#transactionComplete()} + * ou bien qu'on puisse la fermer a la main comme on fait ici, mais on tombe + * sur des NPE :( + * + * Et si on ne les closes pas on arrive tout de suite a 160 connexion + * active rien que pour les tests :( + */ + public void close() { + Connection c; + while ((c = enlistedConnections.poll()) != null) { + try { + if (!c.isClosed()) { + c.close(); + } + } catch (Exception eee) { + if (log.isDebugEnabled()) { + // Il y a des bugs dans dbcp, avec la delegation des + // connections, il arrive que la connection sous jacente soit + // null et dans ce cas si on fait des appels sur c + // pour savoir s'il faut ou non ferme la connexion + // on a un NPE. + // Donc on met seulement en debug le log au lieu de warn. + log.debug("Can't close connection", eee); + } + } + } + } } Modified: trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyExtensionStorageJDBC.java =================================================================== --- trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyExtensionStorageJDBC.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyExtensionStorageJDBC.java 2011-04-29 18:22:17 UTC (rev 852) @@ -96,40 +96,57 @@ public WikittyExtensionStorageJDBC(ApplicationConfig config) { this.config = config; jdbcQuery = WikittyJDBCUtil.loadQuery(config); - Connection connectionTest = WikittyJDBCUtil.getConnection(config); + + WikittyTransaction tx = WikittyTransaction.get(); + boolean txBeginHere = false; try { + if (!tx.isStarted()) { + tx.begin(); + txBeginHere = true; + } + + createDatabase(tx); + + if (txBeginHere) { + tx.commit(); + } + } catch (WikittyException eee) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw eee; + } + } + + protected void createDatabase(WikittyTransaction tx) { + Connection connectionTest = WikittyJDBCUtil.getConnection(tx, config); + try { // If test of existance work, no exception and do nothing // if exception try to create databse Statement statementTest = connectionTest.createStatement(); statementTest.execute(jdbcQuery.getProperty(QUERY_CREATION_EXTENSION_ADMIN_TEST)); statementTest.execute(jdbcQuery.getProperty(QUERY_CREATION_EXTENSION_DATA_TEST)); - } catch(SQLException silentError) { + } catch(Exception silentError) { if (log.isInfoEnabled()) { log.info("try to create extension database"); } - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); statement.execute(jdbcQuery.getProperty(QUERY_CREATION_EXTENSION_ADMIN)); - statement.execute(jdbcQuery.getProperty(QUERY_CREATION_EXTENSION_DATA)); - WikittyJDBCUtil.commitJDBCConnection(connection); - } catch (SQLException eee) { - WikittyJDBCUtil.rollbackJDBCConnection(connection); + statement.execute(jdbcQuery.getProperty(QUERY_CREATION_EXTENSION_DATA)); + } catch (Exception eee) { throw new WikittyException("Can't create table for extension storage", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } - } finally { - WikittyJDBCUtil.closeQuietly(connectionTest); } } - + @Override - public WikittyEvent store(WikittyTransaction transaction, + public WikittyEvent store(WikittyTransaction tx, Collection<WikittyExtension> extensions) throws WikittyException { WikittyEvent result = new WikittyEvent(this); - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { for (WikittyExtension ext : extensions) { // extension id is extension name with version @@ -172,14 +189,12 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't store extension", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public WikittyEvent delete(WikittyTransaction transaction, Collection<String> extNames) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public WikittyEvent delete(WikittyTransaction tx, Collection<String> extNames) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { WikittyEvent result = new WikittyEvent(this); @@ -213,14 +228,12 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't delete extension", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public boolean exists(WikittyTransaction transaction, String id) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public boolean exists(WikittyTransaction tx, String id) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { //select the data with teh id "id" in the admin table String q = String.format(jdbcQuery.getProperty(QUERY_SELECT_WHERE), @@ -233,14 +246,12 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't test extension existance",eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public List<String> getAllExtensionIds(WikittyTransaction transaction) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public List<String> getAllExtensionIds(WikittyTransaction tx) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { List<String> result = new ArrayList<String>(); Statement statement = connection.createStatement(); @@ -256,15 +267,13 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't retrieve all extensions id", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public List<String> getAllExtensionsRequires(WikittyTransaction transaction, + public List<String> getAllExtensionsRequires(WikittyTransaction tx, String extensionName) { - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { List<String> result = new ArrayList<String>(); String q = String.format(jdbcQuery.getProperty(QUERY_SELECT_WHERE), @@ -283,8 +292,6 @@ } catch (SQLException eee) { throw new WikittyException(String.format( "Can't retrieve all extensions required by %s", extensionName), eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @@ -295,12 +302,12 @@ * doesn't exist */ @Override - public String getLastVersion(WikittyTransaction transaction, + public String getLastVersion(WikittyTransaction tx, String extName) { if (lastVersion == null) { // create cache for futur call Map<String, String> tmp = new HashMap<String, String>(); - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); //get all extensions names and versions @@ -320,8 +327,6 @@ lastVersion = tmp; } catch (SQLException eee) { throw new WikittyException("Can't get last version of extensions", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } String result = lastVersion.get(extName); @@ -329,12 +334,12 @@ } @Override - public WikittyExtension restore(WikittyTransaction transaction, String name, String version) + public WikittyExtension restore(WikittyTransaction tx, String name, String version) throws WikittyException { String id = WikittyExtension.computeId(name, version); WikittyExtension result = extensionCache.get(id); if (result == null) { - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { //get the data with the id "id" in the admin table @@ -380,16 +385,14 @@ } catch (SQLException eee) { throw new WikittyException(String.format("Can't load extension %s", id), eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } return result; } @Override - public WikittyEvent clear(WikittyTransaction transaction) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public WikittyEvent clear(WikittyTransaction tx) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { lastVersion = null; WikittyJDBCUtil.doQuery(connection, jdbcQuery.getProperty(QUERY_CLEAR_EXTENSION)); @@ -398,8 +401,6 @@ return result; } catch (Exception eee) { throw new WikittyException("Can't clear all extension", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } } Modified: trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyJDBCUtil.java =================================================================== --- trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyJDBCUtil.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyJDBCUtil.java 2011-04-29 18:22:17 UTC (rev 852) @@ -45,7 +45,6 @@ import javax.transaction.TransactionManager; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.BeanUtils; -import org.apache.commons.dbcp.managed.BasicManagedDataSource; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; @@ -54,6 +53,7 @@ import org.nuiton.util.ApplicationConfig; import org.nuiton.wikitty.WikittyConfigOption; import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.services.WikittyTransaction; /** * @@ -223,8 +223,8 @@ return result; } - private static Map<String, BasicManagedDataSource> dataSources = - new HashMap<String, BasicManagedDataSource>(); + private static Map<String, WikittyManagedDataSource> dataSources = + new HashMap<String, WikittyManagedDataSource>(); /** * Get a new connection instance (i.e. it opens a new transaction) plug on @@ -236,7 +236,12 @@ * @param conf configuration * @return a new Connection (db transaction) */ - public static synchronized Connection getConnectionUnconfigured(ApplicationConfig conf) { + public static synchronized Connection getConnectionUnconfigured( + WikittyTransaction tx, ApplicationConfig conf) { + if (tx == null) { + throw new IllegalArgumentException("WikittyTransaction must not be null"); + } + String driver = conf.getOption( WikittyConfigOption.WIKITTY_STORAGE_JDBC_DRIVER.getKey()); String host = conf.getOption( @@ -249,16 +254,13 @@ String xaDataSourceClassName = conf.getOption( WikittyConfigOption.WIKITTY_STORAGE_JDBC_XADATASOURCE.getKey()); try { - TransactionManager transactionManager = - com.arjuna.ats.jta.TransactionManager.transactionManager(); - String jdbcUrl = String.format("%s:%s@%s", username, password, host); if (!dataSources.containsKey(jdbcUrl)) { log.info("Creating BasicManagedDataSource for: " + jdbcUrl); // Create datasource - BasicManagedDataSource dataSource = new BasicManagedDataSource(); + WikittyManagedDataSource dataSource = new WikittyManagedDataSource(); // if xadatasource if(StringUtils.isNotEmpty(xaDataSourceClassName)) { @@ -295,13 +297,18 @@ dataSource.setUrl(host); dataSource.setUsername(username); dataSource.setPassword(password); - dataSource.setTransactionManager(transactionManager); + TransactionManager tm = tx.getTransactionManager(); + dataSource.setTransactionManager(tm); + dataSources.put(jdbcUrl, dataSource); } - BasicManagedDataSource dataSource = dataSources.get(jdbcUrl); + WikittyManagedDataSource dataSource = dataSources.get(jdbcUrl); Connection connection = dataSource.getConnection(); + // ne surtout pas oublie d'ajouter la connection pour quelle soit + // bien fermee apres un commit ou un rollback + tx.addEnlistedConnection(connection); return connection; } catch(Exception eee) { @@ -315,22 +322,23 @@ } } - /** - * Closes a connection. - * - * @param connection the connection to close - */ - public static void closeQuietly(Connection connection) { - try { - if (connection != null) { - // delegate close can throw NPE - // so this is necessary to catch all Exceptions - connection.close(); - } - } catch (Exception e) { - log.error("Exception while closing connection", e); - } - } + // REMOVED because, we must used WikittyTransaction with jta management +// /** +// * Closes a connection. +// * +// * @param connection the connection to close +// */ +// public static void closeQuietly(Connection connection) { +// try { +// if (connection != null) { +// // delegate close can throw NPE +// // so this is necessary to catch all Exceptions +// connection.close(); +// } +// } catch (Exception e) { +// log.error("Exception while closing connection", e); +// } +// } /** * Get a new connection instance (i.e. it opens a new transaction). @@ -338,9 +346,10 @@ * @return a new Connection (db transaction) * @throws SQLException if the connection fails */ - public static synchronized Connection getConnection(ApplicationConfig config) { + public static synchronized Connection getConnection( + WikittyTransaction tx, ApplicationConfig config) { try { - Connection connection = getConnectionUnconfigured(config); + Connection connection = getConnectionUnconfigured(tx, config); if (connection.getAutoCommit()) { connection.setAutoCommit(false); } @@ -351,45 +360,46 @@ } } - /** - * Closes a connection (i.e. transaction) and commit data. - * - * @param connection the connection to close and commit - */ - public static void commitJDBCConnection(Connection connection) { - try { - connection.commit(); - } catch(SQLException eee) { - throw new WikittyException("Can't commit transaction", eee); - } finally { - try { - connection.close(); - } catch(SQLException eee) { - throw new WikittyException("Can't close connection", eee); - } - } - } + // REMOVED because, we must used WikittyTransaction with jta management +// /** +// * Closes a connection (i.e. transaction) and commit data. +// * +// * @param connection the connection to close and commit +// */ +// public static void commitJDBCConnection(Connection connection) { +// try { +// connection.commit(); +// } catch(SQLException eee) { +// throw new WikittyException("Can't commit transaction", eee); +// } finally { +// try { +// connection.close(); +// } catch(SQLException eee) { +// throw new WikittyException("Can't close connection", eee); +// } +// } +// } +// +// /** +// * Closes a connection (i.e. transaction) and rollback data. +// * +// * @param connection the connection to close and rollback +// */ +// public static void rollbackJDBCConnection(Connection connection) { +// try { +// connection.rollback(); +// } catch(SQLException eee) { +// throw new WikittyException("Can't rollback transaction", eee); +// } finally { +// try { +// connection.close(); +// } catch(SQLException eee) { +// throw new WikittyException("Can't close connection", eee); +// } +// } +// } /** - * Closes a connection (i.e. transaction) and rollback data. - * - * @param connection the connection to close and rollback - */ - public static void rollbackJDBCConnection(Connection connection) { - try { - connection.rollback(); - } catch(SQLException eee) { - throw new WikittyException("Can't rollback transaction", eee); - } finally { - try { - connection.close(); - } catch(SQLException eee) { - throw new WikittyException("Can't close connection", eee); - } - } - } - - /** * Execute query. * * @param connection connection to use Added: trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyManagedDataSource.java =================================================================== --- trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyManagedDataSource.java (rev 0) +++ trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyManagedDataSource.java 2011-04-29 18:22:17 UTC (rev 852) @@ -0,0 +1,88 @@ +package org.nuiton.wikitty.jdbc; + +import java.sql.Connection; +import java.sql.SQLException; +import org.apache.commons.dbcp.managed.BasicManagedDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.pool.impl.GenericObjectPool; + +/** + * Extends BasicManagedDataSource to permit setWhenExhaustedAction configuration + * on GenericObjectPool internal field and change default action to Grow when + * exhausted + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyManagedDataSource extends BasicManagedDataSource { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyManagedDataSource.class); + + /** + * nombre de connexions actives simultanement qui affiche un message + * lorsqu'un message est affiche ce nombre est multiplie par 2 pour le + * prochain message + */ + protected int warnConnectionCount = 10; + protected byte whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; + + /** + * + * @return whenExhaustedAction + * + * @see GenericObjectPool#WHEN_EXHAUSTED_BLOCK + * @see GenericObjectPool#WHEN_EXHAUSTED_FAIL + * @see GenericObjectPool#WHEN_EXHAUSTED_GROW + */ + public byte getWhenExhaustedAction() { + byte result = whenExhaustedAction; + if (connectionPool != null) { + connectionPool.getWhenExhaustedAction(); + } + return result; + } + + /** + * Change whenExhaustedAction of connectionPool + * + * @param whenExhaustedAction + * @see GenericObjectPool#WHEN_EXHAUSTED_BLOCK + * @see GenericObjectPool#WHEN_EXHAUSTED_FAIL + * @see GenericObjectPool#WHEN_EXHAUSTED_GROW + */ + public void setWhenExhaustedAction(byte whenExhaustedAction) { + this.whenExhaustedAction = whenExhaustedAction; + if (connectionPool != null) { + connectionPool.setWhenExhaustedAction(whenExhaustedAction); + } + } + + @Override + protected void createConnectionPool() { + super.createConnectionPool(); + connectionPool.setWhenExhaustedAction(whenExhaustedAction); + } + + @Override + public Connection getConnection() throws SQLException { + Connection result = super.getConnection(); + + int active = connectionPool.getNumActive(); + if (active > warnConnectionCount) { + int idle = connectionPool.getNumIdle(); + warnConnectionCount = warnConnectionCount * 2; + + log.warn(String.format( + "Too many database connection open active:%s idle:%s", + active, idle)); + } + + return result; + } + +} Modified: trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyStorageJDBC.java =================================================================== --- trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyStorageJDBC.java 2011-04-29 18:16:47 UTC (rev 851) +++ trunk/wikitty-jdbc/src/main/java/org/nuiton/wikitty/jdbc/WikittyStorageJDBC.java 2011-04-29 18:22:17 UTC (rev 852) @@ -118,42 +118,55 @@ this.config = config; this.extensionStorage = extensionStorage; jdbcQuery = WikittyJDBCUtil.loadQuery(config); - checkTableOrCreation(); + + WikittyTransaction tx = WikittyTransaction.get(); + boolean txBeginHere = false; + try { + if (!tx.isStarted()) { + tx.begin(); + txBeginHere = true; + } - // all time use alter after creation for binaryValue column because - // this datatype is not portable - checkColumnBinaryOrAlter(); + checkTableOrCreation(tx); + + // all time use alter after creation for binaryValue column because + // this datatype is not portable + checkColumnBinaryOrAlter(tx); + + if (txBeginHere) { + tx.commit(); + } + } catch (WikittyException eee) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw eee; + } } /** * test table existance or create them if necessary */ - protected void checkTableOrCreation() { - Connection connectionTest = WikittyJDBCUtil.getConnection(config); + protected void checkTableOrCreation(WikittyTransaction tx) { + Connection connectionTest = WikittyJDBCUtil.getConnection(tx, config); try { // If test of existance work, no exception and do nothing // if exception try to create databse Statement statementTest = connectionTest.createStatement(); statementTest.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_ADMIN_TEST)); statementTest.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_DATA_TEST)); - } catch (SQLException silentError) { + } catch (Exception silentError) { if (log.isInfoEnabled()) { log.info("try to create wikitty database"); } - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); statement.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_ADMIN)); statement.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_DATA)); - WikittyJDBCUtil.commitJDBCConnection(connection); - } catch (SQLException eee) { - WikittyJDBCUtil.rollbackJDBCConnection(connection); + } catch (Exception eee) { throw new WikittyException("Can't create table for wikitty storage", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } - } finally { - WikittyJDBCUtil.closeQuietly(connectionTest); } } @@ -161,34 +174,28 @@ * Add binary column if necessary * If add can be done, wikitty work for all, except binary type */ - protected void checkColumnBinaryOrAlter() { - Connection connectionTest = WikittyJDBCUtil.getConnection(config); + protected void checkColumnBinaryOrAlter(WikittyTransaction tx) { + Connection connectionTest = WikittyJDBCUtil.getConnection(tx, config); try { // If test of existance work, no exception and do nothing - // if exception try to create databse + // if exception try to create binary column Statement statementTest = connectionTest.createStatement(); statementTest.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_DATA_TEST_BINARY)); - } catch (SQLException silentError) { + } catch (Exception silentError) { if (log.isInfoEnabled()) { log.info("try to alter wikitty database to add binary column"); } - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); statement.execute(jdbcQuery.getProperty(QUERY_CREATION_WIKITTY_DATA_ALTER_BINARY)); - WikittyJDBCUtil.commitJDBCConnection(connection); - } catch (SQLException eee) { - WikittyJDBCUtil.rollbackJDBCConnection(connection); + } catch (Exception eee) { // no exception just log fatal, wikitty can work without this // column but can't store binary. If binary is not used there is // no probleme log.fatal("Can add column to store binary field. You can't use binary", eee); // throw new WikittyException("Can't create table for wikitty storage", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } - } finally { - WikittyJDBCUtil.closeQuietly(connectionTest); } } @@ -217,9 +224,9 @@ } @Override - public WikittyEvent store(WikittyTransaction transaction, + public WikittyEvent store(WikittyTransaction tx, Collection<Wikitty> wikitties, boolean force) throws WikittyException { - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { WikittyEvent result = new WikittyEvent(this); for (Wikitty wikitty : wikitties) { @@ -346,14 +353,12 @@ throw eee; } catch (Exception eee) { throw new WikittyException("Can't store wikitty", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public boolean exists(WikittyTransaction transaction, String id) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public boolean exists(WikittyTransaction tx, String id) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { //select the data with the id "id" in the admin table String q = String.format(jdbcQuery.getProperty(QUERY_SELECT_WHERE), COL_ID, @@ -366,14 +371,12 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't test wikitty existance", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public boolean isDeleted(WikittyTransaction transaction, String id) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public boolean isDeleted(WikittyTransaction tx, String id) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { //select the data with the id "id" in the admin table String q = String.format(jdbcQuery.getProperty(QUERY_SELECT_WHERE), @@ -391,15 +394,13 @@ } } catch (SQLException eee) { throw new WikittyException("Can't test if wikitty is already deleted", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public Wikitty restore(WikittyTransaction transaction, + public Wikitty restore(WikittyTransaction tx, String id, String... fqFieldName) throws WikittyException { - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { //select the data with the id "id" in the admin table String q = String.format(jdbcQuery.getProperty( @@ -418,7 +419,7 @@ sta.setString(1, id); ResultSet dataResultSet = sta.executeQuery(); - Wikitty result = constructWikitty(transaction, id, version, extensionList, + Wikitty result = constructWikitty(tx, id, version, extensionList, dataResultSet, fqFieldName); return result; } else { @@ -428,20 +429,18 @@ } catch (SQLException eee) { throw new WikittyException(String.format( "Can't restore wikitty '%s'", id), eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public WikittyEvent delete(WikittyTransaction transaction, Collection<String> ids) throws WikittyException { - Connection connection = WikittyJDBCUtil.getConnection(config); + public WikittyEvent delete(WikittyTransaction tx, Collection<String> ids) throws WikittyException { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { WikittyEvent result = new WikittyEvent(this); Date now = new Date(); for (String id : ids) { - if (exists(transaction, id) && !isDeleted(transaction, id)) { + if (exists(tx, id) && !isDeleted(tx, id)) { // addVersionUpdate delete date field WikittyJDBCUtil.doQuery(connection, jdbcQuery.getProperty( QUERY_DELETE_WIKITTY_ADMIN), id); @@ -452,14 +451,12 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't delete wikitty", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public void scanWikitties(WikittyTransaction transaction, Scanner scanner) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public void scanWikitties(WikittyTransaction tx, Scanner scanner) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); @@ -476,8 +473,6 @@ } } catch (SQLException eee) { throw new WikittyException("Can't scan whole wikitty", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @@ -491,7 +486,8 @@ * @param fqFieldName minimum field to restore * @return */ - protected Wikitty constructWikitty(WikittyTransaction transaction, String id, String version, String extensionList, + protected Wikitty constructWikitty(WikittyTransaction tx, + String id, String version, String extensionList, ResultSet resultSet, String... fqFieldName) throws SQLException { Set<String> acceptedField = new HashSet<String>(Arrays.asList(fqFieldName)); Wikitty result = new WikittyImpl(id); @@ -501,7 +497,8 @@ String extName = WikittyExtension.computeName(ext); String extVersion = WikittyExtension.computeVersion(ext); - WikittyExtension extension = extensionStorage.restore(transaction, extName, extVersion); + WikittyExtension extension = + extensionStorage.restore(tx, extName, extVersion); result.addExtension(extension); } } @@ -619,8 +616,8 @@ } @Override - public WikittyEvent clear(WikittyTransaction transaction) { - Connection connection = WikittyJDBCUtil.getConnection(config); + public WikittyEvent clear(WikittyTransaction tx) { + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { WikittyJDBCUtil.doQuery(connection, jdbcQuery.getProperty(QUERY_CLEAR_WIKITTY)); WikittyEvent result = new WikittyEvent(this); @@ -628,15 +625,13 @@ return result; } catch (SQLException eee) { throw new WikittyException("Can't clear wikitty data", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } } @Override - public DataStatistic getDataStatistic(WikittyTransaction transaction) { + public DataStatistic getDataStatistic(WikittyTransaction tx) { DataStatistic result; - Connection connection = WikittyJDBCUtil.getConnection(config); + Connection connection = WikittyJDBCUtil.getConnection(tx, config); try { Statement statement = connection.createStatement(); @@ -652,8 +647,6 @@ } catch (SQLException eee) { result = new DataStatistic(); log.warn("Can't retrieve statisticn data", eee); - } finally { - WikittyJDBCUtil.closeQuietly(connection); } return result; }