2014-07-15 2 views
1

배치 프로세스를 호출하고 내 서비스 계층에서 작업 상태를 업데이트해야하는 상황이 있습니다. 여기에 JobRepositoryFactoryBean은 이미 트랜잭션 관리자로 구성되어 있으므로 서비스 메소드에 @Transactional으로 주석을 추가하면 안됩니다. 주석을 달았다면 런타임에 예외가 발생합니다. "Existing transaction detected in job repository please fix and try again by removing @Transactional"@Transactional으로 주석을 달지 않으면 "no session found for current thread"이라는 런타임 예외가 발생합니다. 이 문제를 해결할 수 있도록 도와주세요.JobRepositoryFactoryBean을 사용하는 스프링 배치 프로세스

+0

유스 케이스 사운드가 나에게 전달되었습니다. 작업 상태는 일부 서비스가 아닌 사용자의 흐름에 의해 관리되어야합니다. 유스 케이스에 대해 설명 할 수 있습니까? bean 정의 xml/Class를 추가 할 수 있습니까? –

+0

일괄 처리를 사용하는 사용자 집합에 전자 메일 알림을 보내고 있습니다. 배치 작업을 호출하기 전후에 DB를 사용하여 작업 상태를 업데이트해야합니다. 작업에 대한 추가 정보가 포함 된 상태입니다. 여기서 배치 프로세스는 트랜잭션이지만 DB 작업은 아닙니다. – user2710786

답변

0

서비스는 JobRepositoryFactoryBean 또는 작업 저장소 자체와 직접 상호 작용하면 안됩니다. 스프링 배치 인프라 외부에서 JobRepository API를 사용하지 않는 것이 좋습니다.

데이터베이스 테이블을 사용하면 일괄 작업 실행을 수행하고 작업 및 단계 수준 모두에서 어떤 일이 발생하는지 알 수 있으므로 자세한 내용은 here을 참조하십시오. 작업에 대한 추가 데이터가 필요하다고 생각하는 경우 자신의 테이블을 추가하십시오.

작업 자체의 상태를 업데이트하려면 jobExecution.setExitStatus 또는 jobExecution.setStatus API를 사용하십시오. 차이점 ExitStatus와 BatchStatus here에 대해 읽어보십시오.

귀하의 경우에 청취자를 사용하는 것이 좋습니다. 작업 수신기가 작업 목록 또는 단계 수신기와 달리 청크의 트랜잭션 외부에서 실행됩니다. 그런 다음 다른 트랜잭션 매니저 JobRepostory에 의해 사용되는 하나를 사용하고 있는지 확인

@Component 
public class JobMonitorServiceImpl implements JobMonitorService { 

    @Transactional("transactionManager") 
    public void persistAddtionalData(Object) { 
    } 
} 

직업 XML

<batch:job id="job"> 
     <batch:listeners > 
     <batch:listener ref="jobMonitorListener"/> 
     </batch:listeners> 
... 
</batch:job> 

다음 블로그 게시물을 here

@Component 
public class JobMonitorListener { 
    private static Log LOGGER = LogFactory.getLog(JobMonitorListener.class); 

    @Autowired 
    JobMonitorService monitorService; 
    @BeforeJob 
    public void beforeJob(JobExecution jobExecution){ 
     LOGGER.info("Before Job"); 
     monitorService.persistAddtionalData(date); 
    } 


    @AfterJob 
    public void afterJob(JobExecution jobExecution){ 
     LOGGER.info("Afetr Job"); 
     monitorService.persistAddtionalData(date); 
     jobExecution.setExitStatus(new ExitStatus("Failed by Monitor")); 
     jobExecution.setStatus(BatchStatus.FAILED); 
    } 
} 

서비스를 참조하십시오. 여기에 대한 내 대답을 참조하십시오 Transaction Issue with Spring Batch JobRepository in Unit Test

어쨌든 @Transactional with Spring 배치를 사용하는 것은 까다 롭습니다 (Spring Batch의 프로젝트 책임자 인 Michael Minella의 의견 Spring Batch. Call methods with rollbackFor 참조).

+0

당신의 제안은 좋지만, 좋은 방향이 있지만 여기서 문제는 여러 트랜잭션을 처리 할 수 ​​없다는 것입니다. 나는 그것에 대해 더 많이 배워야 만한다. – user2710786

+0

나는 다음과 같은 것을 잘 모르겠다. –