我们有多个Spring Batch作业,每个作业都使用CommandLineJobRunner在自己的java实例中运行.所有作业同时启动,只读/写平面文件并更新SQL Server中托管的相同Spring Batch元数据.涉及的唯一数据库是Spring Batch元数据数据库.
当多个作业同时启动时,我们会得到SQL死锁异常.可以在下面找到更详细的堆栈跟踪.从数据库的角度来看,我们可以看到死锁受害者正在执行以下操作之一:插入BATCH_JOB_SEQ默认值或从BATCH_JOB_SEQ中删除ID,其中ID <some_number.
我们使用默认的MapJobRegistry,以及默认的作业存储库或指定JobRepositoryFactoryBean.对于用于与Spring Batch数据库交互的数据源,我们使用标准Microsoft SQL Server SQLServerDriver尝试了DriverManagerDataSource或DBCP2池BasicDataSource.我可以上传更具体的配置文件,但在我的测试中,只要我使用SQL Server和标准的Spring配置就会出现问题.
在我的调查中,我认为问题是由于默认的增量器类org.springframework.jdbc.support.incrementer.SqlServerMaxValueIncrementer如何将作业和步骤实例ID与SQL Server数据库表的构造方式相结合.SqlServerMaxValueIncrementer中的代码是同步的,因此如果我们在同一Java实例中运行所有作业,这将不是问题.
如果我们在DB2数据库中实现Spring Batch元数据,我们就没有问题.SQL Server实现使用实际表,DB2实现使用序列对象.
有没有人遇到过这个问题?我只是错过了一些东西吗?似乎每当我们遇到这样的问题时,就像在yyy中设置设置xxx一样简单.如果没有,是否有人知道为什么Spring Batch不在SQL Server实现中实现序列对象?
堆栈跟踪:
[org.springframework.batch.core.launch.support.CommandLineJobRunner] - <Job Terminated in error: Could not increment identity; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 74) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.>
org.springframework.dao.DataAccessResourceFailureException: Could not increment identity;
nested exception is com.microsoft.sqlserver.jdbc.SQLServerException:
Transaction (Process ID 74) was deadlocked on lock resources with another process …Run Code Online (Sandbox Code Playgroud)