-
[JPA] @Scheduled 어노테이션과 트랜잭션 처리이슈 해결 2019. 7. 23. 11:53
회사에서 특정 주기에 따라 사용자들의 상태를 변경하는 서비스가 필요해서 배치 프로그램을 만들려고 했다가 우연히 Okky 사이트를 통해 @Scheduled 어노테이션이 스케쥴링 기능을 제공한다는 것을 알게되서 처음으로 이 기능을 사용해 DB 조작을 해보기로 했다.
대략 코드는 다음과 같았다.
UserStateService
@Service public class UserStateService { @Autowired private UserRepository userRepo; @Scheduled(cron = "10 * * * * *") @transactional public void clearState() { LocalDateTime endDate = LocalDateTime.now(); List<User> findUserList = userRepo.findAllByEndDate(endDate); findUserList.forEach(row -> { row.updateState(false); }); userRepo.saveAll(findUserList); } }
1. find 메소드를 통해 상태를 변경해야할 대상들을 불러온다.
2. 불러온 대상들의 상태를 forEach()를 통해 수정해준다.
3. 수정된 정보를 saveAll()을 통해 저장한다.
문제
스케쥴링 시간이 되어 해당 스케쥴 서비스가 수행될 때 아래와 같은 트랜잭션 요구 에러가 발생했다.
Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
update/delete 쿼리를 사용 중에 트랜잭션이 필요하다는 요구 에러이다.
원인
이미 트랜잭션에 대한 처리는 잘 되고 있는데 왜 이런 문제가 발생하는지 찾아봐도 원하는 내용을 찾기가 쉽지 않았다.
그러던 중 다음과 같은 글을 하나 찾았다.
내용은 트랜잭션 매니저가 @EnableTransactionManagement를 통해 DataSourceTransactionManager로 구성된 경우, 하이버네이트의 begin()메소드가 AbstractTransactionImpl을 부르지 않는다는 것이다.
이로 인해서 @Scheduled를 사용하는 메소드에서 트랜잭션 처리가 불가능하다는 것이다.
트랜잭션 처리를 하기 위해서는 트랜잭션 매니저를 JpaTransactionManager로 구현하라고 되어있다.
해결
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages="com.xxxx.xxx", entityManagerFactoryRef="entityManagerFactory", transactionManagerRef="jpaTransactionManager") public class WebDBConfig { @Bean @ConfigurationProperties(prefix="spring.datasource.hikari") public DataSource myDataSource() { return DataSourceBuilder.create().build(); } @Bean public LocalContainerentityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) { return builder.dataSource(this.myDataSource()) .packages("com.xxxx.xxx") .build(); } @Bean public PlatformTransactionManager jpaTransactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpatransactionManager(entityManagerFactory); } }
그래서 트랜잭션 매니저를 바꿨습니다...
'이슈 해결' 카테고리의 다른 글