Child pages
  • spring batch에서 step id가 같을 경우 발생하는 이슈

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

설을 보내러 가기 전에 spring batch로 만든 부분에 문제가 있어서 확인하는데 이상한 현상을 발견했다. 분명 내가 특정 시간에 실행하려고 했던 Job은 A라는 Job인데 정작 특정 시간에 실행되는 Job은 B가 실행되는 것이었다.

예를 들어 다음과 같이 설정을 했다.

Code Block
<beans ...>
     <job id="expeditionFromWebToGameSyncJob" xmlns="http://www.springframework.org/schema/batch">
          <step id="step">
               <tasklet ref="expeditionFromWebToGameTasklet">
                    <transaction-attributes propagation="REQUIRED" />
               </tasklet>
          </step>
     </job>
      
     <bean id="expeditionFromWebToGameTasklet"
          class="net.slipp.ExpeditionFromWebToGameTasklet" />
</beans>
Code Block
<beans ...>
     <job id="userCharacterFromWebToGameSyncJob" xmlns="http://www.springframework.org/schema/batch">
          <step id="step">
               <tasklet ref="userCharacterFromGameToWebTasklet">
                    <transaction-attributes propagation="REQUIRED"/>
               </tasklet>
          </step>
     </job>
     
     <bean id="userCharacterFromGameToWebTasklet" 
          class="net.slipp.UserCharacterFromGameToWebTasklet"
     />
</beans>

위와 같이 두 개의 Job을 설정하고 Quartz를 활용해 서로 다른 시간에 두 개의 Job이 실행되도록 설정했다. 그런데 expeditionFromWebToGameSyncJob이 실행되어야 하는 시간에 userCharacterFromWebToGameSyncJob이 실행되는 현상이 발생했다. Quartz 설정에서 userCharacterFromWebToGameSyncJob에 대한 설정을 제거했음데도 불구하고 userCharacterFromGameToWebTasklet이 실행되는 현상이 발생했다. 

이리 저리 원인을 찾아본 결과 위 두 개 설정의 step id가 "step"으로 같이 때문에 발생한 이슈였다. 내가 판단했을 때 Job id가 다를 경우 Job 내에 존재하는 Step은 Job에 종속되어 사용될 것으로 생각했다. spring batch의 스키마 또한 Step을 Job과 분리해서 사용하려면 Step의 parent 역할을 할 때 가능하다. 그런데 위와 같이 Step id가 같을 경우 뒤에 로딩된 Step의 id가 활용된다는 것을 확인했다. 아무리 봐도 Step 또한 Spring에서 하나의 bean으로 인식해 서로 간의 공유가 가능하도록 로딩하는 구조로 판단된다. 내부 소스까지 분석해 봤는데 어느 부분에서 이에 대한 처리를 하고 있는지 찾지 못했다. 

이 같은 현상이 발생할 때는 위 설정에서 각 Step의 id를 서로 다르게 사용하면 해결할 수 있다. 나는 각각을 expeditionFromWebToGameSyncStep, userCharacterFromWebToGameSyncStep으로 변경해 문제를 해결했다. 분명 헷갈릴 수 있는 부분이 있기 때문에 주의해서 사용하면 좋겠다.