package se.unlogic.standardutils.dao; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Map.Entry; import javax.sql.DataSource; import se.unlogic.standardutils.dao.querys.ArrayListQuery; import se.unlogic.standardutils.dao.querys.BooleanQuery; import se.unlogic.standardutils.dao.querys.HashMapQuery; import se.unlogic.standardutils.dao.querys.ObjectQuery; import se.unlogic.standardutils.dao.querys.UpdateQuery; import se.unlogic.standardutils.db.DBUtils; public class TransactionHandler { public boolean isAborted() { return aborted; } public boolean isCommited() { return commited; } private final Connection connection; private final ArrayList<UpdateQuery> queryList = new ArrayList<UpdateQuery>(); private boolean aborted; private boolean commited; public TransactionHandler(DataSource dataSource) throws SQLException { super(); this.connection = dataSource.getConnection(); connection.setAutoCommit(false); } public TransactionHandler(Connection connection) throws SQLException { super(); this.connection = connection; connection.setAutoCommit(false); } public UpdateQuery getUpdateQuery(String sqlExpression) throws SQLException { this.checkStatus(); UpdateQuery query = new UpdateQuery(connection, false, sqlExpression); this.queryList.add(query); return query; } public BooleanQuery getBooleanQuery(String sql) throws SQLException { return new BooleanQuery(connection, false, sql); } public <T> ObjectQuery<T> getObjectQuery(String sql, BeanResultSetPopulator<T> populator) throws SQLException { return new ObjectQuery<T>(connection, false, sql, populator); } public <T> ArrayListQuery<T> getArrayListQuery(String sql, BeanResultSetPopulator<T> populator) throws SQLException { return new ArrayListQuery<T>(connection, false, sql, populator); } public <K,V> HashMapQuery<K, V> getHashMapQuery(String sql, BeanResultSetPopulator<? extends Entry<K, V>> populator) throws SQLException{ return new HashMapQuery<K, V>(connection, false, sql, populator); } public synchronized void commit() throws SQLException { this.checkStatus(); try { connection.commit(); this.commited = true; } finally { if (!this.commited) { this.abort(); } else { this.closeConnection(); } } } public synchronized int getQueryCount() { return this.queryList.size(); } public synchronized void abort() { this.checkStatus(); for (UpdateQuery query : queryList) { query.abort(); } if(connection != null){ try { connection.rollback(); } catch (SQLException e) {} } this.closeConnection(); this.aborted = true; } private void closeConnection() { DBUtils.closeConnection(connection); } private void checkStatus() { if (aborted) { throw new TransactionAlreadyAbortedException(); } else if (commited) { throw new TransactionAlreadyComittedException(); } } @Override protected void finalize() throws Throwable { if (!commited && !aborted) { this.abort(); } super.finalize(); } // TODO rename to isClosed public boolean closed() { return commited || aborted; } public static void autoClose(TransactionHandler transactionHandler) { if (transactionHandler != null && !transactionHandler.closed()) { transactionHandler.abort(); } } Connection getConnection() { return connection; } }