この変更を行うためにJDBCInterceptorを登録するだけで、閉じる前にロールバックできます。Abandon は release を呼び出し、disconnect を呼び出すため、Interceptor はこれについて通知されます。たとえば、次のようにできます。
package test;
import java.sql.SQLException;
import oracle.jdbc.OracleConnection;
import org.apache.tomcat.jdbc.pool.ConnectionPool;
import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
import org.apache.tomcat.jdbc.pool.PooledConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RollbackInterceptor extends JdbcInterceptor {
/**
* Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(RollbackInterceptor.class);
/**
* {@inheritDoc}
*/
@Override
public void reset(ConnectionPool parent, PooledConnection con) {
return;
}
/**
* {@inheritDoc}
*/
@Override
public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) {
// if its oracle make sure we rollback here before disconnect just in case a running TX is open
try {
if (con.getConnection().isWrapperFor(OracleConnection.class)) {
if (!con.getConnection().getAutoCommit()) {
LOG.error("Connection {} with Auto-Commit false is going to be closed. Doing an explicit Rollback here!", con);
try {
con.getConnection().rollback();
} catch (SQLException e) {
LOG.error("Failed to rollback connection {} before closing it.", con, e);
}
}
}
} catch (SQLException e) {
LOG.error("Failed to check auto commit of connection {}", con, e);
}
super.disconnected(parent, con, finalizing);
}
}