HHH-10431 - Session-level configurable batch size support

This commit is contained in:
Vlad Mihalcea 2016-05-24 15:53:18 +03:00
parent 5a47abbbfe
commit f18a749c12
6 changed files with 153 additions and 11 deletions

View File

@ -158,4 +158,30 @@ public interface SharedSessionContract extends QueryProducer, Serializable {
*/
@Deprecated
Criteria createCriteria(String entityName, String alias);
/**
* Get the Session-level JDBC batch size for the current Session.
* Overrides the SessionFactory JDBC batch size defined by the {@code hibernate.default_batch_fetch_size} configuration property for the scope of the current {@code Session}.
*
* @return Session-level JDBC batch size
*
* @since 5.2
*
* @see org.hibernate.boot.spi.SessionFactoryOptions#getJdbcBatchSize
* @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize
*/
Integer getJdbcBatchSize();
/**
* Set the Session-level JDBC batch size.
* Overrides the SessionFactory JDBC batch size defined by the {@code hibernate.default_batch_fetch_size} configuration property for the scope of the current {@code Session}.
*
* @param jdbcBatchSize Session-level JDBC batch size
*
* @since 5.2
*
* @see org.hibernate.boot.spi.SessionFactoryOptions#getJdbcBatchSize
* @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize
*/
void setJdbcBatchSize(int jdbcBatchSize);
}

View File

@ -27,7 +27,7 @@ import org.hibernate.service.spi.Manageable;
public class BatchBuilderImpl implements BatchBuilder, Configurable, Manageable, BatchBuilderMXBean {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BatchBuilderImpl.class );
private int size;
private int jdbcBatchSize;
/**
* Constructs a BatchBuilderImpl
@ -38,32 +38,36 @@ public class BatchBuilderImpl implements BatchBuilder, Configurable, Manageable,
/**
* Constructs a BatchBuilderImpl
*
* @param size The batch size to use.
* @param jdbcBatchSize The batch jdbcBatchSize to use.
*/
public BatchBuilderImpl(int size) {
this.size = size;
public BatchBuilderImpl(int jdbcBatchSize) {
this.jdbcBatchSize = jdbcBatchSize;
}
@Override
public void configure(Map configurationValues) {
size = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, size );
jdbcBatchSize = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, jdbcBatchSize );
}
@Override
public int getJdbcBatchSize() {
return size;
return jdbcBatchSize;
}
@Override
public void setJdbcBatchSize(int size) {
this.size = size;
public void setJdbcBatchSize(int jdbcBatchSize) {
this.jdbcBatchSize = jdbcBatchSize;
}
@Override
public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
LOG.tracef( "Building batch [size=%s]", size );
return size > 1
? new BatchingBatch( key, jdbcCoordinator, size )
final Integer sessionJdbcBatchSize = jdbcCoordinator.getJdbcSessionOwner()
.getJdbcBatchSize();
final int jdbcBatchSizeToUse = sessionJdbcBatchSize == null ?
this.jdbcBatchSize :
sessionJdbcBatchSize;
return jdbcBatchSizeToUse > 1
? new BatchingBatch( key, jdbcCoordinator, jdbcBatchSizeToUse )
: new NonBatchingBatch( key, jdbcCoordinator );
}

View File

@ -1156,4 +1156,14 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
return delegate.remapSqlTypeDescriptor( sqlTypeDescriptor );
}
@Override
public Integer getJdbcBatchSize() {
return delegate.getJdbcBatchSize();
}
@Override
public void setJdbcBatchSize(int jdbcBatchSize) {
delegate.setJdbcBatchSize( jdbcBatchSize );
}
}

View File

@ -127,6 +127,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
private transient Boolean useStreamForLobBinding;
private transient long timestamp;
private transient Integer jdbcBatchSize;
protected transient ExceptionConverter exceptionConverter;
public AbstractSharedSessionContract(SessionFactoryImpl factory, SessionCreationOptions options) {
@ -957,6 +959,15 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return exceptionConverter;
}
public Integer getJdbcBatchSize() {
return jdbcBatchSize;
}
@Override
public void setJdbcBatchSize(int jdbcBatchSize) {
this.jdbcBatchSize = jdbcBatchSize;
}
@SuppressWarnings("unused")
private void writeObject(ObjectOutputStream oos) throws IOException {
log.trace( "Serializing " + getClass().getSimpleName() + " [" );

View File

@ -51,4 +51,12 @@ public interface JdbcSessionOwner {
void afterTransactionCompletion(boolean successful, boolean delayed);
void flushBeforeTransactionCompletion();
/**
* Get the Session-level JDBC batch size.
* @return Session-level JDBC batch size
*
* @since 5.2
*/
Integer getJdbcBatchSize();
}

View File

@ -177,4 +177,87 @@ public class BatchingTest extends BaseCoreFunctionalTestCase implements BatchKey
session.close();
}
@Test
public void testSessionBatchingUsage() throws Exception {
Session session = openSession();
session.setJdbcBatchSize( 3 );
SessionImplementor sessionImpl = (SessionImplementor) session;
final JdbcCoordinator jdbcCoordinator = sessionImpl.getJdbcCoordinator();
LogicalConnectionImplementor logicalConnection = jdbcCoordinator.getLogicalConnection();
// set up some tables to use
Statement statement = jdbcCoordinator.getStatementPreparer().createStatement();
String dropSql = getDialect().getDropTableString( "SANDBOX_JDBC_TST" );
try {
jdbcCoordinator.getResultSetReturn().execute( statement, dropSql );
}
catch ( Exception e ) {
// ignore if the DB doesn't support "if exists" and the table doesn't exist
} jdbcCoordinator.getResultSetReturn().execute( statement, "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
assertTrue( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
assertTrue( logicalConnection.isPhysicallyConnected() );
jdbcCoordinator.getResourceRegistry().release( statement );
assertFalse( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
assertTrue( logicalConnection.isPhysicallyConnected() ); // after_transaction specified
// ok, now we can get down to it...
Transaction txn = session.getTransaction(); // same as Session#getTransaction
txn.begin();
final BatchBuilder batchBuilder = new BatchBuilderImpl( 2 );
final BatchKey batchKey = new BasicBatchKey( "this", Expectations.BASIC );
final Batch insertBatch = batchBuilder.buildBatch( batchKey, jdbcCoordinator );
assertTrue( "unexpected Batch impl", BatchingBatch.class.isInstance( insertBatch ) );
final JournalingBatchObserver batchObserver = new JournalingBatchObserver();
insertBatch.addObserver( batchObserver );
final String insertSql = "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )";
PreparedStatement insert = insertBatch.getBatchStatement( insertSql, false );
insert.setLong( 1, 1 );
insert.setString( 2, "name" );
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 0, batchObserver.getImplicitExecutionCount() );
insertBatch.addToBatch();
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 0, batchObserver.getImplicitExecutionCount() );
assertTrue( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
PreparedStatement insert2 = insertBatch.getBatchStatement( insertSql, false );
assertSame( insert, insert2 );
insert = insert2;
insert.setLong( 1, 2 );
insert.setString( 2, "another name" );
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 0, batchObserver.getImplicitExecutionCount() );
insertBatch.addToBatch();
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 0, batchObserver.getImplicitExecutionCount() );
assertTrue( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
PreparedStatement insert3 = insertBatch.getBatchStatement( insertSql, false );
assertSame( insert, insert3 );
insert = insert3;
insert.setLong( 1, 3 );
insert.setString( 2, "yet another name" );
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 0, batchObserver.getImplicitExecutionCount() );
insertBatch.addToBatch();
assertEquals( 0, batchObserver.getExplicitExecutionCount() );
assertEquals( 1, batchObserver.getImplicitExecutionCount() );
assertTrue( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
insertBatch.execute();
assertEquals( 1, batchObserver.getExplicitExecutionCount() );
assertEquals( 1, batchObserver.getImplicitExecutionCount() );
assertFalse( jdbcCoordinator.getResourceRegistry().hasRegisteredResources() );
insertBatch.release();
txn.commit();
session.close();
}
}