📄 abstractbatcher.java
字号:
//$Id: AbstractBatcher.java 11332 2007-03-22 17:34:55Z steve.ebersole@jboss.com $package org.hibernate.jdbc;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.HashSet;import java.util.Iterator;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.AssertionFailure;import org.hibernate.HibernateException;import org.hibernate.Interceptor;import org.hibernate.ScrollMode;import org.hibernate.TransactionException;import org.hibernate.dialect.Dialect;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.exception.JDBCExceptionHelper;import org.hibernate.jdbc.util.FormatStyle;import org.hibernate.util.JDBCExceptionReporter;/** * Manages prepared statements and batching. * * @author Gavin King */public abstract class AbstractBatcher implements Batcher { private static int globalOpenPreparedStatementCount; private static int globalOpenResultSetCount; private int openPreparedStatementCount; private int openResultSetCount; protected static final Logger log = LoggerFactory.getLogger( AbstractBatcher.class ); private final ConnectionManager connectionManager; private final SessionFactoryImplementor factory; private PreparedStatement batchUpdate; private String batchUpdateSQL; private HashSet statementsToClose = new HashSet(); private HashSet resultSetsToClose = new HashSet(); private PreparedStatement lastQuery; private boolean releasing = false; private final Interceptor interceptor; private long transactionTimeout = -1; boolean isTransactionTimeoutSet; public AbstractBatcher(ConnectionManager connectionManager, Interceptor interceptor) { this.connectionManager = connectionManager; this.interceptor = interceptor; this.factory = connectionManager.getFactory(); } public void setTransactionTimeout(int seconds) { isTransactionTimeoutSet = true; transactionTimeout = System.currentTimeMillis() / 1000 + seconds; } public void unsetTransactionTimeout() { isTransactionTimeoutSet = false; } protected PreparedStatement getStatement() { return batchUpdate; } public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException { executeBatch(); logOpenPreparedStatement(); return getCallableStatement( connectionManager.getConnection(), sql, false); } public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException { return prepareStatement( sql, false ); } public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys) throws SQLException, HibernateException { executeBatch(); logOpenPreparedStatement(); return getPreparedStatement( connectionManager.getConnection(), sql, false, getGeneratedKeys, null, null, false ); } public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException, HibernateException { executeBatch(); logOpenPreparedStatement(); return getPreparedStatement( connectionManager.getConnection(), sql, false, false, columnNames, null, false ); } public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException { logOpenPreparedStatement(); return getPreparedStatement( connectionManager.getConnection(), sql, false, false, null, null, false ); } public PreparedStatement prepareQueryStatement( String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException { logOpenPreparedStatement(); PreparedStatement ps = getPreparedStatement( connectionManager.getConnection(), sql, scrollable, scrollMode ); setStatementFetchSize( ps ); statementsToClose.add( ps ); lastQuery = ps; return ps; } public CallableStatement prepareCallableQueryStatement( String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException { logOpenPreparedStatement(); CallableStatement ps = ( CallableStatement ) getPreparedStatement( connectionManager.getConnection(), sql, scrollable, false, null, scrollMode, true ); setStatementFetchSize( ps ); statementsToClose.add( ps ); lastQuery = ps; return ps; } public void abortBatch(SQLException sqle) { try { if (batchUpdate!=null) closeStatement(batchUpdate); } catch (SQLException e) { //noncritical, swallow and let the other propagate! JDBCExceptionReporter.logExceptions(e); } finally { batchUpdate=null; batchUpdateSQL=null; } } public ResultSet getResultSet(PreparedStatement ps) throws SQLException { ResultSet rs = ps.executeQuery(); resultSetsToClose.add(rs); logOpenResults(); return rs; } public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException { ResultSet rs = dialect.getResultSet(ps); resultSetsToClose.add(rs); logOpenResults(); return rs; } public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException { boolean psStillThere = statementsToClose.remove( ps ); try { if ( rs != null ) { if ( resultSetsToClose.remove( rs ) ) { logCloseResults(); rs.close(); } } } finally { if ( psStillThere ) { closeQueryStatement( ps ); } } } public PreparedStatement prepareBatchStatement(String sql) throws SQLException, HibernateException { sql = getSQL( sql ); if ( !sql.equals(batchUpdateSQL) ) { batchUpdate=prepareStatement(sql); // calls executeBatch() batchUpdateSQL=sql; } else { log.debug("reusing prepared statement"); log(sql); } return batchUpdate; } public CallableStatement prepareBatchCallableStatement(String sql) throws SQLException, HibernateException { if ( !sql.equals(batchUpdateSQL) ) { // TODO: what if batchUpdate is a callablestatement ? batchUpdate=prepareCallableStatement(sql); // calls executeBatch() batchUpdateSQL=sql; } return (CallableStatement)batchUpdate; } public void executeBatch() throws HibernateException { if (batchUpdate!=null) { try { try { doExecuteBatch(batchUpdate); } finally { closeStatement(batchUpdate); } } catch (SQLException sqle) { throw JDBCExceptionHelper.convert( factory.getSQLExceptionConverter(), sqle, "Could not execute JDBC batch update", batchUpdateSQL ); } finally { batchUpdate=null; batchUpdateSQL=null; } } } public void closeStatement(PreparedStatement ps) throws SQLException { logClosePreparedStatement(); closePreparedStatement(ps); } private void closeQueryStatement(PreparedStatement ps) throws SQLException { try { //work around a bug in all known connection pools.... if ( ps.getMaxRows()!=0 ) ps.setMaxRows(0); if ( ps.getQueryTimeout()!=0 ) ps.setQueryTimeout(0); } catch (Exception e) { log.warn("exception clearing maxRows/queryTimeout", e);// ps.close(); //just close it; do NOT try to return it to the pool! return; //NOTE: early exit! } finally { closeStatement(ps); } if ( lastQuery==ps ) lastQuery = null; } /** * Actually releases the batcher, allowing it to cleanup internally held * resources. */ public void closeStatements() { try { releasing = true; try { if (batchUpdate!=null) batchUpdate.close(); } catch (SQLException sqle) { //no big deal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -