Java 使用Spring Batch 3的JpaPagingItemReader中的锁获取异常
我将SpringBatch3与SpringBoot一起使用,并实现了一个简单的作业步骤,将标准的JpaPagingItemReader配置为reader。我使用SimpleAsynTaskProcessor并行执行此步骤中的每个块 问题是我收到了一个应用程序。每一万条记录锁定一次例外情况:Java 使用Spring Batch 3的JpaPagingItemReader中的锁获取异常,java,spring,spring-batch,spring-java-config,Java,Spring,Spring Batch,Spring Java Config,我将SpringBatch3与SpringBoot一起使用,并实现了一个简单的作业步骤,将标准的JpaPagingItemReader配置为reader。我使用SimpleAsynTaskProcessor并行执行此步骤中的每个块 问题是我收到了一个应用程序。每一万条记录锁定一次例外情况: javax.persistence.PersistenceException: org.hibernate.exception.LockAcquisitionException: could not extr
javax.persistence.PersistenceException: org.hibernate.exception.LockAcquisitionException: could not extract ResultSet
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:458)
at org.springframework.batch.item.database.JpaPagingItemReader.doReadPage(JpaPagingItemReader.java:219)
at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader$$FastClassBySpringCGLIB$$ebb633d0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at org.springframework.batch.item.database.JpaPagingItemReader$$EnhancerBySpringCGLIB$$3a5ef58b.read(<generated>)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:114)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate$ExecutingRunnable.run(TaskExecutorRepeatTemplate.java:262)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.exception.LockAcquisitionException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:140)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:89)
at org.hibernate.loader.Loader.getResultSet(Loader.java:2065)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
at org.hibernate.loader.Loader.doQuery(Loader.java:909)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
at org.hibernate.loader.Loader.doList(Loader.java:2553)
at org.hibernate.loader.Loader.doList(Loader.java:2539)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
at org.hibernate.loader.Loader.list(Loader.java:2364)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:496)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:231)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449)
... 27 common frames omitted
Caused by: java.sql.SQLException: Die Transaktion (Prozess-ID 67) befand sich auf Sperre Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus.
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2988)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2421)
at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:809)
at net.sourceforge.jtds.jdbc.MSCursorResultSet.processOutput(MSCursorResultSet.java:956)
at net.sourceforge.jtds.jdbc.MSCursorResultSet.cursorCreate(MSCursorResultSet.java:541)
at net.sourceforge.jtds.jdbc.MSCursorResultSet.<init>(MSCursorResultSet.java:154)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:452)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:1029)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:80)
... 43 common frames omitted
我的步骤和项目读取器的定义如下:
/* when job parameter importType = FULL_IMPORT*/
@Bean(name="importIFAPFullStep")
public Step importIFAPFullStep(StepBuilderFactory stepBuilderFactory,
@Qualifier("importIFAPFullReader") ItemReader<Product> reader,
@Qualifier("importIFAPWriter") ItemWriter<Product> writer,
@Qualifier("importIFAPProcessor") ItemProcessor<Product, Product> processor) {
return stepBuilderFactory.get("importIFAPFullStep")
.<Product, Product> chunk(Integer.valueOf(env.getProperty("importIFAPFullStep.chunk.size")))
.faultTolerant()
.retryPolicy(new NeverRetryPolicy()) //cannot retry due to multi-threaded nature
.skipLimit(Integer.valueOf(env.getProperty("importIFAPFullStep.skip.limit")))
.skip(RuntimeException.class)
.listener(new ItemSkipListener())
.reader(reader)
.processor(processor)
.writer(writer)
.taskExecutor(new SimpleAsyncTaskExecutor("iifs")) //new ManagedExecutorService())
.throttleLimit(Integer.valueOf(env.getProperty("importIFAPFullStep.throttle.limit")))
.build();
}
/* Reader*/
@Bean(name="importIFAPFullReader", destroyMethod="")
@StepScope
public JpaPagingItemReader<Product> importIFAPFullReader() {
JpaPagingItemReader<Product> reader = new JpaPagingItemReader<Product>();
reader.setEntityManagerFactory(emFactoryBean.getObject());
reader.setTransacted(false);
reader.setPageSize(Integer.valueOf(env.getProperty("importIFAPFullReader.page.size")));
reader.setSaveState(false); //job not restartable due to multithreaded nature
reader.setQueryString("select new com.docmorris.pib.ifap.model.Product(p.id, p.pzn, p.clientId, p.version) from Product p order by p.pzn desc");
return reader;
}
我使用SQLServer2012作为数据库实现。我假设这些异常不会发生,因为JpaPagingItemReader是安全的,我正在开箱即用
我尝试了其他几个TaskExecutor实现,并尝试了许多其他方法,但似乎没有任何效果
有人能给我指出正确的方向吗?这与sqlserver有关吗
我在启动时看到了这个警告,如果与此相关,我会犹豫:
o、 s.b.a.batch.BasicBatchConfigurer:JPA不支持自定义隔离级别,因此在启动作业时可能不会锁定
我检查了源代码,spring boot似乎总是将隔离级别设置为隔离默认值。但这可能是工作回购的唯一隔离级别,我不确定:
许多thx的任何反馈
问候,
金姆