Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

769
Visualizações
Spring Batch Deadlock: no se pudo incrementar la identidad; la excepción anidada es com.microsoft.sqlserver.jdbc.SQLServerException

Estamos en el proceso de pasar a Azure SQL Server desde Oracle DB para nuestra aplicación Spring Batch.

Recibo el siguiente error al intentar ejecutar dos trabajos diferentes al mismo tiempo que actualiza tablas diferentes, pero usa las mismas tablas BATCH_ comunes

Causado por: org.springframework.dao.DataAccessResourceFailureException: no se pudo incrementar la identidad; La excepción anidada es com.microsoft.sqlserver.jdbc.SQLServerException: la transacción (ID de proceso 167) se interbloqueó en los recursos de bloqueo con otro proceso y se eligió como víctima del interbloqueo. Vuelva a ejecutar la transacción. en org.springframework.jdbc.support.incrementer.SqlServerMaxValueIncrementer.getNextKey(SqlServerMaxValueIncrementer.java:124) ~[bat-applybatch-jobs-2.2.12-SNAPSHOT.jar:?] en org.springframework.jdbc.support.incrementer. AbstractDataFieldMaxValueIncrementer.nextLongValue(AbstractDataFieldMaxValueIncrementer.java:125)

Configuración de mi repositorio de trabajos

 <job-repository id="jobRepository" isolation-level-for-create="READ_COMMITED" />

interbloqueo de la base de datos

 <deadlock> <victim-list> <victimProcess id="process2a41675a4e8" /> </victim-list> <process-list> <process id="process2a41675a4e8" taskpriority="0" logused="280" waitresource="RID: 6:9:24682488:29" waittime="4984" ownerId="696000712" transactionname="implicit_transaction" lasttranstarted="2021-12-29T12:18:30.153" XDES="0x29a22bc4428" lockMode="U" schedulerid="4" kpid="52760" status="suspended" spid="173" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-12-29T12:18:30.157" lastbatchcompleted="2021-12-29T12:18:30.153" lastattention="1900-01-01T00:00:00.153" clientapp="Microsoft JDBC Driver for SQL Server" hostname="ServerName" hostpid="0" loginname="LoginName" isolationlevel="read committed (2)" xactid="696000712" currentdb="6" currentdbname="Database" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058"> <executionStack> <frame procname="unknown" queryhash="0xadc42a7474869694" queryplanhash="0x238c4f9df8a5d6cc" line="1" stmtstart="26" stmtend="146" sqlhandle="0x020000007654041849f4ffe980c136b592ccbe8260983e220000000000000000000000000000000000000000"> unknown </frame> <frame procname="unknown" queryhash="0xadc42a7474869694" queryplanhash="0x238c4f9df8a5d6cc" line="1" stmtend="126" sqlhandle="0x0200000045a2af306ade799ae9ffa65edc0f722c526e26330000000000000000000000000000000000000000"> unknown </frame> </executionStack> <inputbuf> delete from LoginName.BATCH_STEP_EXECUTION_SEQ where ID &lt; 10899 </inputbuf> </process> <process id="process2a42d680ca8" taskpriority="0" logused="420" waitresource="RID: 6:9:24682490:8" waittime="4984" ownerId="696000707" transactionname="implicit_transaction" lasttranstarted="2021-12-29T12:18:30.153" XDES="0x2a41ae18428" lockMode="U" schedulerid="7" kpid="53280" status="suspended" spid="129" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-12-29T12:18:30.153" lastbatchcompleted="2021-12-29T12:18:30.153" lastattention="1900-01-01T00:00:00.153" clientapp="Microsoft JDBC Driver for SQL Server" hostname="ServerName" hostpid="0" loginname="LoginName" isolationlevel="read committed (2)" xactid="696000707" currentdb="6" currentdbname="Database" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058"> <executionStack> <frame procname="unknown" queryhash="0xadc42a7474869694" queryplanhash="0x238c4f9df8a5d6cc" line="1" stmtstart="26" stmtend="146" sqlhandle="0x020000007654041849f4ffe980c136b592ccbe8260983e220000000000000000000000000000000000000000"> unknown </frame> <frame procname="unknown" queryhash="0xadc42a7474869694" queryplanhash="0x238c4f9df8a5d6cc" line="1" stmtend="126" sqlhandle="0x02000000a0f1f51de77e1eefa19367c42fc9d1938c2075020000000000000000000000000000000000000000"> unknown </frame> </executionStack> <inputbuf> delete from LoginName.BATCH_STEP_EXECUTION_SEQ where ID &lt; 10898 </inputbuf> </process> </process-list> <resource-list> <ridlock fileid="9" pageid="24682488" dbid="6" objectname="162589bb-bc36-4834-8bdc-e58a2deca742.LoginName.BATCH_STEP_EXECUTION_SEQ" id="lock2a043bbcc00" mode="X" associatedObjectId="72057594071547904"> <owner-list> <owner id="process2a42d680ca8" mode="X" /> </owner-list> <waiter-list> <waiter id="process2a41675a4e8" mode="U" requestType="wait" /> </waiter-list> </ridlock> <ridlock fileid="9" pageid="24682490" dbid="6" objectname="162589bb-bc36-4834-8bdc-e58a2deca742.LoginName.BATCH_STEP_EXECUTION_SEQ" id="lock29f5f1b7f00" mode="X" associatedObjectId="72057594071547904"> <owner-list> <owner id="process2a41675a4e8" mode="X" /> </owner-list> <waiter-list> <waiter id="process2a42d680ca8" mode="U" requestType="wait" /> </waiter-list> </ridlock> </resource-list> </deadlock>

intentado:

 <job-repository id="jobRepository" isolation-level-for-create="READ_UNCOMMITED" /> <job-repository id="jobRepository" isolation-level-for-create="ISOLATION_REPEATABLE_READ" /> <job-repository id="jobRepository" isolation-level-for-create="SERIALIZABLE" />

He creado las tablas como se destaca a continuación.

 CREATE TABLE BATCH_STEP_EXECUTION_SEQ ( ID BIGINT IDENTITY(<last Oracle sequence value>, 1) ); CREATE TABLE BATCH_JOB_EXECUTION_SEQ ( ID BIGINT IDENTITY(<last Oracle sequence value>, 1) ); CREATE TABLE BATCH_JOB_SEQ ( ID BIGINT IDENTITY(<last Oracle sequence value>, 1) );

¿cual es el problema? ¿Cómo puedo solucionar esto?

Actualización: definición de trabajo

 <bean id="simpleStep" class="org.springframework.batch.core.step.factory.SimpleStepFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager" /> <property name="jobRepository" ref="jobRepository" /> <property name="startLimit" value="100" /> <property name="commitInterval" value="1" /> </bean>

Actualización # 2: ¿Puedo probar algo como esto?

 <bean id="informixIncrementer" class="com.bah.batch.informixsupport.InformixMaxValueIncrementerFactory"><property name="dataSource" ref="dataSource" /> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean" isolation-level-for-create="READ_COMMITTED" table-prefix="BATCH_"> <property name="incrementerFactory" ref="informixIncrementer"/> </bean>
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Me temo que este es un error conocido en Spring Batch 4.x que actualmente solo está planeado para resolverse con Spring Batch 5, que no se espera hasta dentro de un par de meses: https://github.com/spring- proyectos/lote de primavera/problemas/3927

Puede emular la corrección haciendo ajustes locales como en la confirmación de la corrección: https://github.com/spring-projects/spring-batch/commit/fe911c8456bb49a69b1c84c78c0a0e0fdf224803 , es decir

  • Ajustar el esquema para que contenga secuencias.
  • Cambie el DataFieldMaxValueIncrementerFactory que se usa para construir el JobRepository .

No creo que esto último sea factible con una configuración XML pura. La discusión sobre este tema contiene algunos consejos sobre cómo se puede hacer en Java: https://github.com/spring-projects/spring-batch/issues/1448

La personalización concreta depende de las personalizaciones que ya tenga, pero debería funcionar al menos aproximadamente de la siguiente manera. Puede aplicar la fábrica de incrementadores con un BatchConfigurer :

 @Bean public BatchConfigurer batchConfigurer(DataSource dataSource) { return new DefaultBatchConfigurer(dataSource) { @Override protected JobRepository createJobRepository() throws Exception { JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); factory.setDataSource(getDataSource()); factory.setTransactionManager(getTransactionManager()); factory.setIncrementerFactory(new MyIncrementerFactory(getDataSource())); factory.afterPropertiesSet(); return factory.getObject(); } }; }

donde

 public class MyIncrementerFactory implements DataFieldMaxValueIncrementerFactory { private final DataSource dataSource; public MyIncrementerFactory(DataSource dataSource) { this.dataSource = dataSource; } @Override public DataFieldMaxValueIncrementer getIncrementer(String databaseType, String incrementerName) { return new SqlServerSequenceMaxValueIncrementer(dataSource, incrementerName); } @Override public boolean isSupportedIncrementerType(String databaseType) { return true; } @Override public String[] getSupportedIncrementerTypes() { return null; // method should not get called anyway } }

y SqlServerSequenceMaxValueIncrementer debe ser el incrementador de la confirmación.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda