• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

영속성 컨텍스트 동시성...? 관련 질문입니다

23.11.26 21:12 작성 23.11.26 21:13 수정 조회수 166

0

em.flush를 명시적으로 적어주거나, 트랜잭션이 끝나서 커밋이 될 때 DB에 쿼리를 날리는 JPA에 관해서 궁금한게 있습니다.

 

DB 제약은 복합키로 되어있고 insert 하는 상황에서 궁금증이 있는데요

 

동일한 복합키를 가진건 DB쿼리를 그대로 날려도 Exception을 뱉어서 실제 DB에는 들어가지 않는다는 것은 알고 있습니다.

 

다만 궁금한게 순수히 오로지 JPA로만 해결이 가능한 문제인지 궁금증이 있습니다.

 

id와 name은 사용자로 부터 요청 받은 부분이고

Member requetMember = new Member(id,name);

Optional<Member> m = repository.findByIdAndName(id,name);

if(m.isPresent()){
repository.insert(requestMember);
}

 

제가 궁금한 상황은 멀티서버 환경에서 실행 되는 쓰레드가 2개 있다고 했을때

 

동시에 2번의 요청을 보내고 2개 모두 예외는 발생하지 않아야 하는 상황입니다.

 

 

A,B 쓰레드 모두 m.isPresent() 코드를 통과 하였고

그 와중에 A 쓰레드가 실행될때, insert까지 마치고 트랜잭션 커밋까지 이루어진 상황에서

 

B쓰레드가 repository.insert(requestMember);

이 부분을 실행 할 때 에러가 나는걸 방지 할 수 있는지 궁금합니다.

 

JPA로 해보려다 딱히 방안이 생각나지 않아서

insert 할 때 sql로

 

insert into member

select id , name

where not exist(select * from member where id='id', name='name')

 

이런식으로 insert 할 때 select를 1번의 쿼리로 하면서 하고있는데요, 이런 경우는 어떻게 해야할까요?

답변 1

답변을 작성해보세요.

0

안녕하세요. ariwarabbang님

이 경우는 JPA로 막을 수 없습니다. 대신에 데이터베이스 제약조건 때문에 예외가 발생하게 됩니다.

데이터베이스 예외를 확인하시고, 해당 예외가 발생할 때 예외를 잡아서 후처리 하는 방식을 사용해야 합니다.

추가로 다음 내용도 읽어보시면 도움이 되실거에요.

https://www.inflearn.com/questions/59250

감사합니다.