Transactional 에너테이션 누락

By | 2021년 1월 31일
Table of Contents

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 가 호출된다.

답글 남기기