sql server—运行spring批处理作业的多个示例时发生死锁

xjreopfe  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(490)

我有一个spring批处理作业,它从数据库中读取数据,并在执行一些处理后,以基于块的步骤写入文件。我的要求是同时并行运行几乎16个作业示例,只是使用不同的作业参数。
但在这么做的过程中,我一直面临着几个问题。
1.
无法为事务打开jdbc连接。嵌套异常为java.sql.sqltransientconnectionexception:hikaripole-1-连接不可用。
异常:无法增加标识。嵌套异常为com.microsoft.sqlserver.jdbc.sqlserverexception:事务(进程id 124)在与其他进程的锁资源上被死锁,并被选为死锁受害者。重新运行事务。
通过设置 IsolationLevel 以及修改元数据表,如下所示。
像这样为create设置隔离级别

JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setIsolationLevelForCreate("ISOLATION_REPEATABLE_READ");

让dba向每个seq表添加索引,如下所示(jet是我将repo表放入的模式):

ALTER TABLE [JET].[BATCH_JOB_EXECUTION_SEQ]
ADD CONSTRAINT [BATCH_JOB_EXECUTION_SEQ_PK] PRIMARY KEY CLUSTERED ([ID] ASC)
GO

ALTER TABLE [JET].[BATCH_JOB_SEQ]
ADD CONSTRAINT [BATCH_JOB_SEQ_PK] PRIMARY KEY CLUSTERED ([ID] ASC)
GO

ALTER TABLE [JET].[BATCH_STEP_EXECUTION_SEQ]
ADD CONSTRAINT [BATCH_STEP_EXECUTION_SEQ_PK] PRIMARY KEY CLUSTERED ([ID] ASC)
GO

但我仍然面临着这个问题。
ps:spring批处理已经部署到aks(azurekubernetes服务),并使用azuresqlserver作为数据源。

wxclj1h5

wxclj1h51#

基于中的讨论https://github.com/spring-projects/spring-batch/issues/1448,这个问题似乎是由 SqlServerMaxValueIncrementer 来自spring框架,不使用sqlserver的本机序列。以下是javadoc的摘录:

There should be one sequence table per table that needs an auto-generated key.

Example:

create table tab (id int not null primary key, text varchar(100))
create table tab_sequence (id bigint identity)
insert into tab_sequence default values

这可能是因为sqlserver直到最近才支持序列。但我想这就是为什么springbatch使用表来模拟mssqlserver的序列。
我建议您尝试将默认ddl更改为使用序列而不是表:

CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ ;
CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ ;
CREATE SEQUENCE BATCH_JOB_SEQ ;

这是基于mssqlserver文档的默认序列定义。这应该可以,但是如果需要,您可以自定义它们。
您可能还需要提供一个自定义 DataFieldMaxValueIncrementer 这是基于序列的(因为spring框架中的一个使用表),并通过 DataFieldMaxValueIncrementerFactory (见 JobRepositoryFactoryBean#setIncrementerFactory ).

相关问题