java - 春季批处理中的OptimisticLockingFailureException
问题描述
我正面临 org.springframework.dao.OptimisticLockingFailureException: Attempt to update step execution id=xxx with wrong version (0),其中当前版本在我的应用程序中为 0。它正在工作,最近它开始在任何 Spring 批处理作业启动时抛出此异常(我们使用 Spring 批处理从 excel 批量导入和从 DB 导出文件,总共有 6 个作业)
异常是在第一步引发的,它只是从昨天开始发生,因为它之前工作正常。相同的代码适用于不同的环境。
深入挖掘 Spring Batch 源代码,我发现它正在尝试使用 step_execution_id 和 where 子句中的 version 更新行,但没有更新行。然后它抛出这个异常来通知是否有任何并发修改。但它试图更新的版本是 0,当前版本也是 0。很多人都问过这个问题,但是更新版本和当前版本是有区别的,在我的情况下是一样的。
我正在使用 Spring Batch 3.0.8 和 Hibernate 5.4.1。
我也尝试过清除春季批处理表。尝试重新启动,重新部署等。
PS - 请原谅我的英语。
解决方案
当 2 个作业同时针对不同的数据服务器运行时,会发生 OptimisticLockingFailureException。看起来以下 BATCH 表被创建为复制表。
- BATCH_JOB_EXECUTION
- BATCH_JOB_EXECUTION_CONTEXT
- BATCH_JOB_EXECUTION_PARAMS
- BATCH_JOB_EXECUTION_SEQ
- BATCH_JOB_INSTANCE
- BATCH_JOB_SEQ
- BATCH_STEP_EXECUTION
- BATCH_STEP_EXECUTION_CONTEXT
- BATCH_STEP_EXECUTION_SEQ
作业序列 ID 和执行 ID 分别通过递增 BATCH_JOB_EXECUTION_SEQ 和 BATCH_JOB_SEQ 表中的当前值来创建。当您同时针对不同的数据服务器运行作业时,这将导致问题,因为从技术上讲,两个作业可以具有相同的作业执行 ID。
在我们的应用程序中,我们遇到了同样的问题。JOB1 & JOB2同时启动。JOB1针对DATASERVER1启动,JOB2同时针对DATASERVER2启动。在我们的例子中,JOB1和JOB2都使用相同的执行 ID 20000002345 ,这从DATASERVER1和DATASERVER2中的不一致数据可以看出。这导致 JOB1 失败,因为步骤表中的版本在 DATASERVER2 中途发生了更改。我们得到了以下异常。
异常: org.springframework.dao.OptimisticLockingFailureException:尝试使用错误版本 (1) 更新步骤异常 id=20000002345,当前版本为 2
由于重复的步骤执行 ID,JOB2 也失败了。
异常: 原因:org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) 值 (?, ?, ?, ?)]; 键 1 的重复条目“1”;嵌套异常是 com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 1
解决方案: 我们要求 DBA关闭 所有数据服务器(DATASERVER1、DATASERVER2、DATASERVER3 等)上的 BATCH 表(9 个表以上)的复制。这解决了问题。在我们关闭复制后,这个问题永远不会发生。
推荐阅读
- angular - 在页面/计算机关闭之前运行功能/服务
- django - 将对象传递给表单让我 __init__() 得到了一个意外的关键字参数“实例”
- html - 使用 javascript 创建的样式表
- javascript - 两个函数之间的javascript范围问题
- c# - 运算符“>=”不能应用于“字符串”和“整数”类型的操作数
- python - Skilearn ImportError:DLL加载失败:找不到指定的模块
- python - 使用张量板回调时出现 CUPTI 错误
- flutter - Flutter 镜像版本问题
- eclipse - 在 Eclipse 中调试 Maven 目标
- angular - Angular dart - 带有 ngModel 的自定义输入组件