강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

탁형님의 프로필 이미지
탁형

작성한 질문수

실전! Querydsl

사용자 정의 리포지토리

사용자 정의 리포지토리에서 변경이 일어나는 경우 @Transactional을 붙여줘야 하나요?

작성

·

968

0

사용자 정의 리포지토리에 insert문을 이용한 부분이 있는데, 예외가 발생하여 @Transactional을 붙여 해결했습니다. (업무 중에 급하게 검색하여 적용한 관계로 에러 메세지와 세부 내용은 기억을 못하고 있습니다ㅠㅠ)

정확히는 네이티브 쿼리를 이용한 bulk insert 였습니다.

혹시 update나 insert문을 쓸 경우에는 직접 구현한 메소드에 @Transactional을 붙여줘야 하는건지, 아니면 다른 이유로 문제가 발생한건지 궁금합니다.

퀴즈

71%나 틀려요. 한번 도전해보세요!

스프링 데이터 JPA 사용 시 순수 JPA와 비교하여 개발 생산성 측면에서 얻는 주요 이점은 무엇일까요?

모든 쿼리를 수동으로 복잡하게 작성해야 한다

기본 CRUD(저장, 조회 등) 메서드를 인터페이스만으로 자동으로 제공받는다

모든 동적 쿼리 구현이 항상 완전히 자동화된다

데이터베이스 연결 설정을 직접 XML 파일로 관리해야 한다

답변 5

2

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 탁형님

JPA의 모든 데이터 변경은 트랜잭션 안에서 일어나야 합니다. 따라서 트랜잭션을 붙여주는 것이 맞습니다.

(그런데 리포지토리 계층 보다는 서비스 계층에 붙여주는게 더 나은 선택이겠지요?)

참고로 스프링 데이터 JPA의 기본 구현체는 SimpleJpaRepository는 모든 데이터 변경에 @Transactional을 제공합니다. save() 같은 곳에 적용이 되어 있습니다.

감사합니다.

0

김영한님의 프로필 이미지
김영한
지식공유자

탁형님 혹시 서비스 계층에 javax.transaction.Tansactional이 import 되어있는지 양쪽에 확인해주세요^^

만약 서비스 계층에 org.springframework.transaction.annotation.Transactional이 잡혀있는데, 문제가 발생하는 것이면

전체 프로젝트를 압축해서 올려주세요.

감사합니다.

0

탁형님의 프로필 이미지
탁형
질문자

에러 메세지는 다음과 같습니다.

Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query

jpql로 변경을 처리한 경우에는 말씀하신 것처럼 repository 계층에서 따로 @Transactional을 붙여주지 않아도 잘 동작합니다.

native query를 이용한 부분에서만 위 에러가 발생하고 있습니다.

0

김영한님의 프로필 이미지
김영한
지식공유자

스프링의 트랜잭션은 기본적으로 전파되기 때문에 문제없이 동작해야 하는 것이 맞습니다.

그래서 저도 정확한 이유를 모르겠습니다.

혹시 오류 메시지를 찾으면 말씀해주세요.

0

탁형님의 프로필 이미지
탁형
질문자

빠른 답변 감사드립니다.

분명히 서비스 계층에서 붙여줬었는데도 불구하고 에러가 발생해서 Custom Repository 메소드에도 추가로 @Transactional을 붙여줬었습니다.

- 서비스 계층 코드

@Transactional
public void saveCallMessages(String senderIp, String cid, List<STTMessage> messages) {
...
callMessageRepository.bulkInsert(callMessages);
}

- Repository 계층 코드

@Override
@Transactional
public int bulkInsert(List<CallMessage> messages) {
StringBuilder sb = new StringBuilder("insert into call_messages ( ... ) values ");

...

em.createNativeQuery(sb.toString()).executeUpdate();
return messages.size();
}

에러 메세지를 복사해 놓았어야 했는데 죄송합니다ㅜㅜ

탁형님의 프로필 이미지
탁형

작성한 질문수

질문하기