HibernateCursorItemReader 结果集已经关闭
HibernateCursorItemReader Result set already closed
我正在使用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 上我遇到过。可能是本地 spring 启动速度更快。
关于如何避免这种情况的任何想法?
问题是 spring-batch 在每个块之后都会提交,提交会关闭事务,从而关闭结果集。
当您不在应用程序容器中时,例如当您使用 spring 启动时,*CursorItemReaders 使用单独的连接来绕过事务,从而避免关闭游标结果集的提交。
另一方面,如果您 运行 在应用程序服务器上,您从服务器管理的 数据源 获得的连接将默认参与事务.为了使游标项 reader 工作,您必须设置不参与事务的 数据源 。a
或者,您可以使用 *PagingItemReader,它读取每个块的 页大小 条记录,每个记录都在一个单独的事务中。这样就完全避免了关闭结果集的问题。 注意: 如果底层 table 在块之间发生变化,结果可能不是您所期望的!
我正在使用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 上我遇到过。可能是本地 spring 启动速度更快。
关于如何避免这种情况的任何想法?
问题是 spring-batch 在每个块之后都会提交,提交会关闭事务,从而关闭结果集。
当您不在应用程序容器中时,例如当您使用 spring 启动时,*CursorItemReaders 使用单独的连接来绕过事务,从而避免关闭游标结果集的提交。
另一方面,如果您 运行 在应用程序服务器上,您从服务器管理的 数据源 获得的连接将默认参与事务.为了使游标项 reader 工作,您必须设置不参与事务的 数据源 。a
或者,您可以使用 *PagingItemReader,它读取每个块的 页大小 条记录,每个记录都在一个单独的事务中。这样就完全避免了关闭结果集的问题。 注意: 如果底层 table 在块之间发生变化,结果可能不是您所期望的!