일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 자바의 신
- Java8
- facade pattern
- 자바8
- Stream
- 스트림
- Template Method Pattern
- 자바
- CQRS
- spring Batch
- Was
- Java8 in action
- 디자인 패턴
- SERVLET
- jsp
- web
- Clean Code
- spring
- 자바8인액션
- domain
- AWS101
- head first
- ddd
- 패스트캠퍼스
- Java in action
- Java
- Java 8 in action
- Design Pattern
- 클린코드
- spring boot
- Today
- Total
주난v 개발 성장기
Spring Batch DuplicateKeyException 발생 본문
org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED, JOB_CONFIGURATION_LOCATION) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; (conn=21562) Duplicate entry '0' for key 'PRIMARY'; nested exception is java.sql.SQLIntegrityConstraintViolationException: (conn=21562) Duplicate entry '0' for key 'PRIMARY'
에러가 발생!!
최초에 batch 라이브러리에 있는 schema-mysql.sql 파일을 보고 테이블 생성
배치 동작 --> 성공
배치 재동작 --> 실패...위와 같은 오류를 계속 뱉음.
나는 저 테이블에 관여한 적이 없는데...왜 자꾸 나는지?
코드를 확인해보니...
SimpleJobRepository에서 JobExecutionDao.saveJobExecution(jobExecution)
--> JdbJobExecutionDao의 saveJobExecution 메소드에서 incrementVersion 메소드를 통해, Job을 돌릴 때마다, version = version + 1을 하여
BATCH_JOB_EXECUTION 테이블에 데이터를 넣고 있음.
이 때 바라보는 테이블이 BATCH_JOB_EXECUTION_SEQ 테이블로 유추되고, 이 테이블의 값을 증가시켜, BATCH_JOB_EXECUTION 데이터를 등록하는 형태로 보임.
하지만, 최초 생성 후 배치를 동작해도 BATCH_JOB_EXECUTION_SEQ 테이블에 데이터가 쌓이지 않았음.
자동으로 쌓아줘야할 것으로 보이는데, 일단 SpringBoot 2.2.* 대의 버그라는 글을 다수 보았고, 다시 sql 파일을 열어보았더니
INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);
INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
이런식의 존재 여부를 체크 후 없으면 데이터를 추가해주는 쿼리를 제공해주고 있었음.
이 쿼리를 통해 해당 Exception 해결하였음.
일단 코드를 더 확인해봐야 할 필요가 있고, 정확한 문제는 아니지만 exist를 체크해서 insert를 한다는 것은 무엇인가 안들어갈 케이스를 대비한 것으로 보임.
***
해당 글은 잠깐의 코드 분석을 통해 작성한 글로 해결책은 된다하더라도 정확한 해결방법은 아닐 수 있습니다.
다른 의견이나 잘못된 판단이라고 생각되시면 댓글 부탁드립니다.
***
'개발 성장기 > Spring Framework' 카테고리의 다른 글
[SpringBoot] DB 정보없이 서버 띄우기 (0) | 2020.03.19 |
---|