Hibernate flush 和 hibernate.jdbc.batch_size 配置大小的关系(附Hibernate源代码分析)

这几天在做性能优化的项目,发现我修改了hibernate.jdbc.batch_size 为50后,性能提升并不明显。经过仔细分析hibernate源代码,发现hibernate默认给batch_size为15.

看一下hibernate是如何赋值默认15的:


我们写入数据库时,有可能这样写:

@Test
public void insertChineseBook() throws Exception {
....
/**
* 每100次向数据库flush一次
*/
if (i % 100 == 0) {
session.flush();
}
}
....
}

希望每100次向数据库flush一次,但是这里flush的时候,hibernate会每15条往数据库写入一次。

看hibernate的源代码:


org.hibernate.engine.jdbc.batch.internal.BatchingBatch.class

@Override
public void addToBatch() {
try {
currentStatement.addBatch();
}
catch ( SQLException e ) {
LOG.debugf( "SQLException escaped proxy", e );
throw sqlExceptionHelper().convert( e, "could not perform addBatch", currentStatementSql );
}
statementPosition++;
if ( statementPosition >= getKey().getBatchedStatementCount() ) {
batchPosition++;

/*大家注意到了没,hibernate会判断当前的batch里面已经有了多少条待执行的sql(batchPosition 变量),如果待执行的条数等于batchSize(就是hibernate.jdbc.batch_size ),那么执行performExecution */

if ( batchPosition == batchSize ) {
notifyObserversImplicitExecution();
performExecution();
batchPosition = 0;
}
statementPosition = 0;
}
}

performExecution执行的就是:statement.executeBatch(),这个是jdbc原生的语句了。


看一下flush的全过程序列图吧:


(图片有点大,看不清,请使用右键,在新标签中打开图片)



版权声明:本文为sophistwu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。