티스토리 뷰

Programing/TIL

20190528

oh-yes 2019. 5. 28. 21:27
20190528

1. @Transactional

회사 업무 중, 테스트 환경에서 적절하게 @Transactional을 부여하지 못해서 실수한 부분이 있어서 메모하려고 한다.

Repository를 의존하고 있는 서비스 레이어에서 명시적으로 @Transactional을 서비스 매서드에 마킹 해놓지 않은 상태에서 해당 서비스 메서드의 호출이 종료된 시점에 @OneToMany(FetchType.Lazy)로 마킹된 하위 모델 엔티티가 조회를 시도하게 되면서 생기는 문제였다.

기본적으로 Data JPA에서의 Repository는 CRUD 오퍼레이션에 대해 트랜잭션을 가져가게 되는데, 문제가 되는 상황은 엔티티에서 FetchType.Lazy를 사용했을 때, 즉 지연 로딩을 사용할 때가 문제가 되는 듯 했다. 만약 레파지토리에서의 트랜잭션을 재정의하고 싶다면 아래와 같이 재정의를 하면 되고, 또한 readOnly 와 같은 속성을 사용하여 Replication 구조상에서 해당 트랜잭션이 Read Replication을 참조하도록 변경하는 것도 가능하다.

public interface UserRepository extends CrudRepository<User, Long> {

  @Override
  @Transactional(timeout = 10)
  public List<User> findAll();
}

또한, 만약 클래스 레벨에서의 @Transactional의 속성 값이 readOnly=true로 지정되어 있고, 매서드가 READ 오퍼레이션이 아닌 CUD 오퍼레이션을 취한다면 아래와 같이 @Modifying을 붙여서 트랜잭션을 재정의 하는 것이 가능하다고 한다.

@Transactional(readOnly = true)
public interface UserRepository extends JpaRepository<User, Long> {

  List<User> findByLastname(String lastname);

  @Modifying
  @Transactional
  @Query("delete from User u where u.active = false")
  void deleteInactiveUsers();
}

'Programing > TIL' 카테고리의 다른 글

20190609  (0) 2019.06.10
20190603  (0) 2019.06.03
20190526  (0) 2019.05.26
20190507  (0) 2019.05.07
20190504  (0) 2019.05.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함