HibernateCursorItemReader结果集已关闭

时间:2015-10-09 16:46:22

标签: java hibernate session spring-batch

我正在使用Spring批处理HibernateCursorItemReader,它的定义如下

    <bean class="org.springframework.batch.item.database.HibernateCursorItemReader"
      scope="step" id="priceListFctrItemReader">
    <property name="queryName" value="FIND_ALL_PRICE_LIST_FCTR_ITEM_ID_BY_MONTRY_FCTR_VER"/>
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="parameterValues">
        <map>
            <entry key="factorVersion" value="#{jobParameters['current.factor.version']}"/>
            <entry key="trueValue" value="#{true}"/>
        </map>
    </property>
</bean>

小结果似乎没问题。但是如果处理需要很长时间,那么会话就会关闭,我得到了

org.hibernate.exception.GenericJDBCException: could not advance using next()
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)

并进一步向下

Caused by: java.sql.SQLException: Result set already closed
at weblogic.jdbc.wrapper.ResultSet.checkResultSet(ResultSet.java:144)
at weblogic.jdbc.wrapper.ResultSet.preInvocationHandler(ResultSet.java:93)

我没有在spring-boot中遇到过这种情况,但是在weblogic上我做到了。可能是本地弹簧靴更快。

关于如何避免这种情况的任何想法?

1 个答案:

答案 0 :(得分:2)

问题是spring-batch在每个chunk之后执行提交,并且提交会关闭事务,从而关闭结果集。

如果您不在应用程序容器中,就像使用Spring引导时一样,* CursorItemReaders使用单独的连接来绕过事务,从而避免关闭游标结果集的提交。

另一方面,如果您在应用程序服务器上运行,则从服务器托管数据源获得的连接将默认参与事务。为了使游标项目阅读器起作用,您必须设置一个不参与交易的数据源 a

或者,您可以使用* PagingItemReader读取每个块的页面大小记录,每个记录都在一个单独的事务中。这完全避免了关闭结果集的问题。 注意:如果基础表在块之间发生变化,结果可能与您的预期不符!

[a]:https://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-2-restart-cursor-based-reading-and-listeners/