尝试 运行 多个实例上的批处理作业时出现 DuplicateKey 异常
DuplicateKey Exception while trying to run the batch job on multiple Instances
我是运行集群中的批处理作业,同时具有相同的参数。虽然,它只在一个实例上是 运行 很好,但我得到的例外是:
Detail: Key (job_name, job_key)=(offlineTicketRefreshJob, c5d36835a13fd8ae0e91a69a6fa1c2d8) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "job_inst_un"
我原以为它会给出 JobAlreadyRunningException 或其他异常。我认为批处理作业存储库的隔离级别也是可序列化的,那么为什么它会给出 PSQLException?
如果您在作业存储库上正确配置隔离级别,则不会发生这种情况。您没有分享您的作业存储库配置,但您可以在 Configuring a JobRepository and Transaction Configuration for the JobRepository 部分找到示例:
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setTransactionManager(transactionManager);
factory.setIsolationLevelForCreate("ISOLATION_SERIALIZABLE");
factory.setTablePrefix("BATCH_");
factory.setMaxVarCharLength(1000);
return factory.getObject();
}
积极的隔离级别可防止在集群环境中创建重复的作业实例。 SERIALIZABLE
和 READ_COMMITTED
应该有效。
我是运行集群中的批处理作业,同时具有相同的参数。虽然,它只在一个实例上是 运行 很好,但我得到的例外是:
Detail: Key (job_name, job_key)=(offlineTicketRefreshJob, c5d36835a13fd8ae0e91a69a6fa1c2d8) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "job_inst_un"
我原以为它会给出 JobAlreadyRunningException 或其他异常。我认为批处理作业存储库的隔离级别也是可序列化的,那么为什么它会给出 PSQLException?
如果您在作业存储库上正确配置隔离级别,则不会发生这种情况。您没有分享您的作业存储库配置,但您可以在 Configuring a JobRepository and Transaction Configuration for the JobRepository 部分找到示例:
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setTransactionManager(transactionManager);
factory.setIsolationLevelForCreate("ISOLATION_SERIALIZABLE");
factory.setTablePrefix("BATCH_");
factory.setMaxVarCharLength(1000);
return factory.getObject();
}
积极的隔离级别可防止在集群环境中创建重复的作业实例。 SERIALIZABLE
和 READ_COMMITTED
应该有效。