package org.simpleflatmapper.jdbc.impl;
import org.simpleflatmapper.jdbc.SQLFunction;
import org.simpleflatmapper.jdbc.TransactionTemplate;
import org.simpleflatmapper.util.ErrorHelper;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSourceTransactionTemplate implements TransactionTemplate {
private final DataSource dataSource;
public DataSourceTransactionTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public <R> R doInTransaction(SQLFunction<? super Connection, ? extends R> sqlFunction) throws SQLException {
Connection connection = dataSource.getConnection();
try {
R r = sqlFunction.apply(connection);
commit(connection);
return r;
} catch (Throwable e) {
handleError(e, connection);
return null; // never reached
} finally {
close(connection);
}
}
private void commit(Connection connection) throws SQLException {
if (!connection.getAutoCommit()) {
connection.commit();
}
}
private void handleError(Throwable e, Connection connection) throws SQLException {
try {
if (!connection.getAutoCommit()) {
connection.rollback();
}
} catch(Throwable t) {
// swallow not to mask original error
}
ErrorHelper.rethrow(e);
}
private void close(Connection connection) {
try {
connection.close();
} catch (Throwable t) {
// swallow
}
}
}