HHH-10431 - Session-level configurable batch size support
This commit is contained in:
parent
5a47abbbfe
commit
f18a749c12
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() + " [" );
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue