当前位置: 首页 > 知识库问答 >
问题:

Spring批处理无法获取最后一个_insert_id();嵌套的例外是java。sql。SQLException:超过了锁等待超时;

姚高爽
2023-03-14

我正在使用Spring批处理3.0.5。在MySQL数据库上发布。我有一个从多个表中读取并处理记录并在完成后标记其状态的作业。作业数据的设计方式是,同一作业的多个实例可以运行,而不会踩到彼此的脚趾...(他们有自己的数据集可以使用)

我有以下作业存储库配置。

protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix(TABLE_PREFIX);
    factory.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
    factory.afterPropertiesSet();
    return  factory.getObject();
}

当我运行此作业的多个实例时,我会在一段时间后获得以下异常。一些实例成功完成,但一些实例由于此异常而失败。

[12-04-2015 17:08:06,276] [Thread 39] ERROR org.springframework.batch.core.job.AbstractJob: Encountered fatal error executing job
org.springframework.batch.core.JobExecutionException: Flow execution ended unexpectedly
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:140)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at org.springframework.core.task.SimpleAsyncTaskExecutor$ConcurrencyThrottlingRunnable.run(SimpleAsyncTaskExecutor.java:251)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.batch.core.job.flow.FlowExecutionException: Ended flow=SuspendAccountFlow at state=SuspendAccountFlow.partitionAccountListStep with exception
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:178)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134)
    ... 4 more
Caused by: org.springframework.dao.DataAccessResourceFailureException: Could not obtain last_insert_id(); nested exception is java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
    at org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer.getNextKey(MySQLMaxValueIncrementer.java:118)
    at org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer.nextLongValue(AbstractDataFieldMaxValueIncrementer.java:128)
    at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.buildStepExecutionParameters(JdbcStepExecutionDao.java:187)
    at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.saveStepExecution(JdbcStepExecutionDao.java:118)
    at org.springframework.batch.core.repository.support.SimpleJobRepository.add(SimpleJobRepository.java:170)
    at sun.reflect.GeneratedMethodAccessor81.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy25.add(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor81.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy25.add(Unknown Source)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:144)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
    ... 6 more
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2541)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1604)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1535)
    at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
    at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)

到目前为止,我一直在努力跟进。

  1. 增加DB中的锁等待时间。
  2. 将序列表的类型从InnoDB更改为MyISAM。将类型更改为MyISAM后,所有作业开始失败。但是不同的例外。
  3. 将作业存储库的事务隔离级别设置为ISOLATION_READ_COMMITTED

到目前为止,上面没有任何帮助。请分享你的想法。

共有1个答案

秦景福
2023-03-14

请检查您正在使用的数据库。如果您使用的是MySQL,那么在上下文中。xml文件,数据库类型应为mysql。我用的是postgresql,所以我用的是postgres。可接受的databaseType格式如下

DERBY、DB2、DB2ZOS、HSQL、SQLSERVER、MYSQL、ORACLE、POSTGRES、SYBASE、H2

我的JobRepository bean如下

<bean id="jobRepository"
    class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseType" value="postgres" />
</bean>
 类似资料:
  • 在eclipse中为我的spring项目进行junit测试时,我遇到了一个失败, 无法获得JDBC连接;嵌套异常是java.sql.SQLExc0019:拒绝用户'root'@'localhost'的访问(使用密码:是) 我已经将jar文件添加到库中,并设置了环境变量路径。但它仍然给出了错误。 测试功能如下所示。 我的pom.xml档案也附后。

  • 问题内容: 我正在使用Hibernate,试图模拟2个并发更新到数据库中的同一行。 编辑:我将em1.getTransaction()。commit移到em1.flush()之后;我没有收到任何StaleObjectException,两个事务已成功提交。 我在上遇到以下异常。为什么? 问题答案: 好吧,您正试图陷入僵局,并且成功了:-) Transaction1开始,与您的实体更新(和锁定)行。

  • 问题内容: 我的服务器上正在运行应用程序。此应用程序的问题在于,每天我将获得近10-20,仅是我的SP之一。这是我的SP, 此SP有任何问题吗?为什么我仅在此SP中收到超时异常?这是堆栈跟踪, 问题答案: 您需要在服务器端对此进行调查,以了解执行超时的原因。请注意,服务器没有超时,该超时是由上默认的30秒引起的。 Waits和Queues是一个很好的资源,它是一种诊断SQL Server性能瓶颈的

  • 在Spring批处理中,对数据库的读写操作最多可完成31 000条记录。在31 000条记录之后,会出现以下异常: 即使我在Connection属性中引发了超时,我仍然会得到相同的异常。

  • 现在我想让所有的期货最多等待n秒,直到全部完成。我知道我可以调用,但是如果我在循环中对我的所有期货顺序地调用它,则超时开始增加。伪代码: 块会出现超时,直到结果就绪。因此,如果第一个在超时之前完成,第二个也在超时之前完成,依此类推,则整个执行时间最多为而不是。 因此,我正在寻找一个方法,它接受的列表和一个超时,并行运行所有的结果,然后返回一个未来结果的集合。有什么想法吗?

  • 因为我在C()捕获异常,并且只使用日志记录来处理它,而在B()中没有任何捕获,所以我在A()捕获异常吗? 还是应该在C()抛出异常,并在B()添加try catch以便能够在a()中处理它?