스프링데이터 + JPA/웹 애플리케이션 개발

13. 회원 서비스

sdafdq 2023. 11. 6. 11:48
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;

    @Transactional
    public Long join(Member member){
        validateDuplicateMember(member);
        Long memberId = memberRepository.save(member);
        return memberId;
    }


    private void validateDuplicateMember(Member member) {
        List<Member> findMembers = memberRepository.findByName(member.getName());

        if(!findMembers.isEmpty()){
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }

    public List<Member> findMembers(){
        return memberRepository.findAll();
    }

    public Member findOne(Long memberId){
        return memberRepository.findOne(memberId);
    }
}

엔티티를 통한 데이터 변경은 트랜잭션 안에서 이루어 져야 한다.

그래서 @Transactional 저렇게 하면 모든 메소드에 붙는다.

그런데 readOnly = true

저거 하면 약간의 최적화가 된다. db갈때도 이건 readOnly 용이야~ 하면서 가기 때문

근데 저렇게 join처럼 readOnly가 아닌 것 들은 따로 트랜잭셔널을 지정해준다.

기본이 readOnly = false기 때문에 readOnly가 아니다.

 

간단한 검증. 저거는 그냥 런타임에러를 던져준다. 나중에 따로 커스텀에러 만들어서 통합 에러 처리 할 것 같다.

근데 저것도 문제가 있다. 동시성 문제. 멀티쓰레드 기 때문에 동시에 memberA로 가입하면 둘다 동시에 가입될 수 있다.

그래서, 최후의 방어벽을 위해 SQL 테이블 자체에서 name을 유니크 제약 조건으로 잡는 게 좋다.

 

 

 

 

'스프링데이터 + JPA > 웹 애플리케이션 개발' 카테고리의 다른 글

15. 상품 개발  (0) 2023.11.07
14. 회원 테스트  (0) 2023.11.06
12. 회원 리포지토리  (0) 2023.11.06
11. 애플리케이션 아키텍처  (0) 2023.11.05
10. 구현 요구사항  (0) 2023.11.05