티스토리 뷰

반응형

 

캡스톤 프로젝트 도중

매핑 테이블의 삭제 문제와 트랜잭션 처리에 대해

학습한 내용을 정리하고

포스팅하려고 한다.

 

M:N(다대다) 관계를 별도의 매핑 테이블을 구성하고

이를 엔티티로 처리하는 경우에는 주의해야 한다.

 

'명사'에 해당하는 데이터를 삭제하는 경우에

중간 매핑 테이블에서도 삭제를 해야하기 때문이다!

 

예를 들어 다음과 같은 경우에서

예시 상황

 

특정 회원(Member)을 삭제하는 경우

회원이 등록한 모든 디자인 댓글(Reply) 역시 삭제되어야 한다.

 

member 테이블에서 특정 회원을 삭제하려면 우선

reply 테이블에서 먼저 삭제하고, member 테이블을 삭제해야 한다.

 

이 2개의 작업은 하나의 트랜잭션으로 관리해야한다.

 

 

이제 코드로 들어가 확인해보자. 

 


 

ReplyRepository에서 다음과 같이

deleteByMember를 추가한다.

 

ReplyRepository

 

MemberRepositoryTests에서 member를 삭제하는 메서드를 작성한다.

MemberRepositoryTests

 

메서드를 실행해보면 결과는 다음과 같다.

test 메서드 실행 결과

 

다음과 같이 에러가 뜨는 것을 확인할 수 있는데

에러메세지를 자세히 보자.

 

에러 메세지

 

참조 무결성 제약조건을 위반해 에러가 발생하는 것인데

원인은 이것 때문이다.

 

1. FK를 가지는 Reply 쪽을 먼저 삭제하지 않았고

2. 트랜잭션 관련 처리가 없기 때문이다.

 

따라서 삭제하는 단계를 FK 쪽을 먼저 삭제하도록 수정하고 메서드의 선부에

@Transactional과 @Commit을 추가해 해결해야한다.

 

자, 다시 해결해보자.

 

memberRepositoryTests

 

새로 작성한 testDeleteMember 메서드이다.

 

test method 실행 결과

 

test method가 정상적으로 작동하는 걸 확인할 수 있다.

 

 

하지만 이 코드는 조금 비효율적이다.

예를 들어 reply 테이블에 '2'번 회원이 작성한 디자인 댓글이 총 3개가 있다고 하면

3개의 데이터를 삭제한다고 생각하면 당연히

where 조건에 member_member_code 컬럼을 이용해서

한 번에 3개의 데이터가 삭제될 것처럼 보이지만

실제로 실행되는 sql은 아래와 같이 reply 테이블에서

3번 반복적으로 실행된 후에 member 테이블을 삭제한다.

 

여러 번 반복되는 코드(비효율적)

 

이렇게 비효율적인 코드를 막기 위해서는

ReplyRepository에서 @Query를 이용해서 where절을 지정하는 것이 더 나은 방법이다.

 

(updatedelete를 이용하기 위해서는 

@Modifying 어노테이션이 반드시 필요하다.)

 

 

MemberRepositoryTests

 

다음과 같이 memberRepositoryTests를 수정하고 실행해보자.

 

테스트 케이스 실행 결과

 

문제 없이 실행되는 것을 볼 수 있다.

 


그럼 오늘도 열공하자. 😊

반응형