public <V,E extends Exception> V executeTransaction(
		Class<E> eClass,
		DatabaseCallableE<V,E> callable
	) throws SQLException, E {
		DatabaseConnection conn = transactionConnection.get();
		if(conn!=null) {
			// Reuse existing connection
			try {
				return callable.call(conn);
			} catch(RuntimeException err) {
				conn.rollback();
				throw err;
			} catch(NoRowException err) {
				throw err;
			} catch(SQLException err) {
				conn.rollbackAndClose();
				throw err;
			} catch(Exception e) {
				conn.rollback();
				if(eClass.isInstance(e)) throw eClass.cast(e);
				throw new SQLException(e);
			}
		} else {
			// Create new connection
			conn=createDatabaseConnection();
			try {
				transactionConnection.set(conn);
				try {
					V result = callable.call(conn);
					conn.commit();
					return result;
				} finally {
					transactionConnection.remove();
				}
			} catch(RuntimeException | NoRowException err) {
				conn.rollback();
				throw err;
			} catch(SQLException err) {
				conn.rollbackAndClose();
				throw err;
			} catch(Exception e) {
				conn.rollback();
				if(eClass.isInstance(e)) throw eClass.cast(e);
				throw new SQLException(e);
			} finally {
				conn.releaseConnection();
			}
		}
	}
public <V,E extends Exception> V executeTransaction(
		Class<E> eClass,
		DatabaseCallableE<V,E> callable
	) throws SQLException, E {
		DatabaseConnection conn = transactionConnection.get();
		if(conn!=null) {
			
			try {
				return callable.call(conn);
			} catch(RuntimeException err) {
				conn.rollback();
				throw err;
			} catch(NoRowException err) {
				throw err;
			} catch(SQLException err) {
				conn.rollbackAndClose();
				throw err;
			} catch(Exception e) {
				conn.rollback();
				if(eClass.isInstance(e)) throw eClass.cast(e);
				throw new SQLException(e);
			}
		} else {
			
			conn=createDatabaseConnection();
			try {
				transactionConnection.set(conn);
				try {
					V result = callable.call(conn);
					conn.commit();
					return result;
				} finally {
					transactionConnection.remove();
				}
			} catch(RuntimeException | NoRowException err) {
				conn.rollback();
				throw err;
			} catch(SQLException err) {
				conn.rollbackAndClose();
				throw err;
			} catch(Exception e) {
				conn.rollback();
				if(eClass.isInstance(e)) throw eClass.cast(e);
				throw new SQLException(e);
			} finally {
				conn.releaseConnection();
			}
		}
	}
public < V , E extends Exception > V executeTransaction ( Class < E > eClass , DatabaseCallableE < V , E > callable ) throws SQLException , E { DatabaseConnection conn = transactionConnection . get ( ) ; if ( conn != null ) { // Reuse existing connection try { return callable . call ( conn ) ; } catch ( RuntimeException err ) { conn . rollback ( ) ; throw err ; } catch ( NoRowException err ) { throw err ; } catch ( SQLException err ) { conn . rollbackAndClose ( ) ; throw err ; } catch ( Exception e ) { conn . rollback ( ) ; if ( eClass . isInstance ( e ) ) throw eClass . cast ( e ) ; throw new SQLException ( e ) ; } } else { // Create new connection conn = createDatabaseConnection ( ) ; try { transactionConnection . set ( conn ) ; try { V result = callable . call ( conn ) ; conn . commit ( ) ; return result ; } finally { transactionConnection . remove ( ) ; } } catch ( RuntimeException | NoRowException err ) { conn . rollback ( ) ; throw err ; } catch ( SQLException err ) { conn . rollbackAndClose ( ) ; throw err ; } catch ( Exception e ) { conn . rollback ( ) ; if ( eClass . isInstance ( e ) ) throw eClass . cast ( e ) ; throw new SQLException ( e ) ; } finally { conn . releaseConnection ( ) ; } } }
<p>
Executes an arbitrary transaction, providing automatic commit, rollback, and connection management.
Rolls-back the transaction on RuntimeException.
Rolls-back the transaction on NoRowException on the outer-most transaction only.
Rolls-back and closes the connection on all SQLException except NoRowException.
Rolls-back the transaction on E.
</p>
<p>
The connection allocated is stored as a ThreadLocal and will be automatically reused if
another transaction is performed within this transaction.  Any nested transaction will automatically
become part of the enclosing transaction.  For safety, a nested transaction will still rollback the
entire transaction on any exception.
</p>

@see #isInTransaction()
<p > Executes an arbitrary transaction providing automatic commit rollback and connection management . Rolls - back the transaction on RuntimeException . Rolls - back the transaction on NoRowException on the outer - most transaction only . Rolls - back and closes the connection on all SQLException except NoRowException . Rolls - back the transaction on E . < / p > <p > The connection allocated is stored as a ThreadLocal and will be automatically reused if another transaction is performed within this transaction . Any nested transaction will automatically become part of the enclosing transaction . For safety a nested transaction will still rollback the entire transaction on any exception . < / p >