본문 바로가기

개발중/Spring Batch

[Spring Batch] 낙관적 잠금 오류 (OptimisticLockingFailureException) 해결하기

728x90
반응형

서론

현대의 소프트웨어 개발에서 병렬 처리와 데이터 동시성은 필수적이지만, 이로 인해 예상치 못한 오류에 직면할 때가 많습니다. 본 포스트에서는 Spring Batch에서 흔히 발생하는 OptimisticLockingFailureException 오류를 다루고, 이를 flush() 메소드를 사용하여 해결한 경험을 공유하고자 합니다. 이 오류가 프로젝트에 미치는 영향을 이해하고 대처법을 배우는 것은 모든 데이터 중심 애플리케이션 개발자에게 중요할 것입니다.

문제 상세 설명

OptimisticLockingFailureException은 낙관적 잠금 기법을 사용할 때 발생합니다. 이 기법은 동시에 같은 데이터에 여러 트랜잭션이 접근하려 할 때 사용되는데, 데이터 무결성을 보장하기 위해 데이터의 버전을 체크합니다. 문제는 업데이트하려는 데이터의 버전이 기대하는 버전과 맞지 않을 때 발생합니다. 이 오류가 발생한 환경은 Spring Framework 5와 Hibernate를 사용한 서버 측 애플리케이션에서였으며, 복잡한 데이터 처리 로직이 포함된 배치 작업 중에 주로 발생했습니다.

 

org.springframework.dao.OptimisticLockingFailureException: Attempt to update step execution id=321 with wrong version (1), where current version is 2
	at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.updateStepExecution(JdbcStepExecutionDao.java:291) ~[spring-batch-core-5.1.0.jar!/:5.1.0]

 


해결 방법

flush() 메소드는 Hibernate Session의 변경 내용을 데이터베이스에 즉시 반영하도록 강제합니다. 이 방법을 통해, 데이터베이스와 애플리케이션의 상태 불일치를 해결할 수 있었습니다. 아래는 해당 메소드를 적용한 코드 예시입니다:

 

    @Override
    public void write(Chunk<? extends VehicleRecallInfo> chunk){
            for(VehicleRecallInfo x : chunk.getItems()){
                System.out.println(x.toString());
                hyundaiRepository.save(x);
                hyundaiRepository.flush();
            }
    }

 

 

이 외에도 세션의 캐시를 클리어하거나 트랜잭션 재시도 로직을 구현하는 방법도 고려했으나, flush()를 사용한 방법이 이 상황에서 가장 효과적이었습니다.

728x90
반응형