Table of Content
Transactional 에너테이션 누락
삽질 기록을 남깁니다.
Transactional 누락
@Service
public class DailyStockSummaryService {
// @Transactional
public void applyStockChange(StockChangeDto stockChangeDto) {
DailyStockSummaryKey key = new DailyStockSummaryKey();
key.setYyyymmdd(stockChangeDto.getYyyymmdd());
key.setSkuCd(stockChangeDto.getSkuCd());
DailyStockSummary entity = get(key);
// ......
repository.save(entity);
}
// ......
}
Persistable 을 구현해서 select 가 이중으로 호출되는 것을 막았음에도, 아래에 이중으로 select 가 호출된다.
Hibernate: select dailystock0_.sku_cd as sku_cd1_1_0_, dailystock0_.yyyymmdd as yyyymmdd2_1_0_, dail .....
Hibernate: select dailystock0_.sku_cd as sku_cd1_1_0_, dailystock0_.yyyymmdd as yyyymmdd2_1_0_, daily ......
Hibernate: update db_summary.tbl_daily_stock_summary set lastupdate=?, available_stock_no=?, bad_stock_no=?, btb_ch ......
오류 해결
@Transactional
을 붙여주면 문제가 해결된다.
@Service
public class DailyStockSummaryService {
@Transactional
public void applyStockChange(StockChangeDto stockChangeDto) {
DailyStockSummaryKey key = new DailyStockSummaryKey();
key.setYyyymmdd(stockChangeDto.getYyyymmdd());
key.setSkuCd(stockChangeDto.getSkuCd());
DailyStockSummary entity = get(key);
// ......
repository.save(entity);
}
// ......
}
트랜젝션을 걸어주지 않으면, 이미 select 해 놓은 데이타가 삭제되지 않았음에 대한 보장이 없으므로, 매번 새로 select 하는가 보다.
오류 원인
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
service 레이어에서 Transactional
을 설정해 주지 않으면, 디폴트로 repository 에 각각의 메소드에 설정된 트랜젝션이 작동한다.
public interface UserRepository extends CrudRepository<User, Long> {
@Override
@Transactional(timeout = 10)
public List<User> findAll();
// Further query method declarations
}
Persistable
을 설정했다고 해도, repository 메소드 각각에 대한 트랜잭션이 되기에, repository.save(entity);
도 별도의 트랜잭션으로 작동하고 엔터티가 있는지 없는지를 체크할 수밖에 없어, select 가 호출된다.