Skip to main content Link Menu Expand (external link) Document Search Copy Copied

created at 2022-12-18

1. spring-data-jpa save(S entity)

본 프로젝트에서는 Service Layer에서 트랜젝션처리를 수행한다. 또한 Repository는 data-jpa를 사용했다. 필자는 서비스 내 예외 발생 시, 원하는 값을 반환하고싶었다. 따라서 service내 try-catch로 UniqueKeyViolation 예외발생 시 값을 반환하는 코드를 추가했다. 하지만, 문제는 data-jpa에서 발생했다. save시, 먼저 select후 insert되는 점이였다. 만약 같은 id값을 가지는 객체가 존재한다면 persist가 아닌 merge가 되었었다.

즉, save는 이미 같은 key를 가지는 데이터가 존재하면 변경감지하여 update하며, 없을때만 insert되기에 예외처리가 수행되지 않았다.

아래는 data-jpa에서의 save() 이다.

@Transactional
@Override
public <S extends T> S save(S entity) {
    if (entityInformation.isNew(entity)) {
        em.persist(entity); // 원하는 흐름. 이쪽으로 갔을 때, UniqueKeyViolation 예외 발생한다.
        return entity;
    } else {
        return em.merge(entity); // 하지만 이쪽으로 흘러갔다.
    }
}

따라서 data-jpa를 사용하기 위해선 먼저 서비스에서 userRepository.findById(user.getUserId())과정을 필수적으로 작성해야한다.

    // userService
    @Override
    public ResponseEntity<?> save(User user) {
        Optional<User> findUser = userRepository.findById(user.getUserId());
        if (findUser.isPresent()) {
            return ResponseEntity.badRequest().body("해당 ID로 등록된 유저가 존재합니다");
        }
        userRepository.save(user);
        return ResponseEntity.ok(user);
    }

(Appendix) HTTP 와 Kafka

기존 HTTP 통신을 Kafka 로 변경하려고 한다. 실험적으로 기존 HTTP 통신 중 유저 회원가입을 이벤트 스트림으로 만들려고한다. 하지만 Kafka 는 HTTP와 다르게 기본적으로 Request/Response 형식이 아니다. 그래서 토픽을 user.create.req / user.create.res 이렇게 만들어 줘야지 Request/Response 형식으로 사용할 수 있다.

PostMapping("/user/{userId}")이런 url로 가져왔던 부분들을 수정해야한다. 즉, producer은 json에 모든 request 내용을 담아 전송하고 consumer에서 이를 읽는 Request/Response 형식으로 작성해야한다.

아래의 포스팅은 필자가 하고자 하는 방향인 Kafka를 Request/Response로 사용하는 것에 대한 고찰을 확인할 수 있다.

If you build a modern enterprise architecture and new applications, apply the natural design patterns that work best with the technology. Remember: Data streaming is a different technology than web services and message queues! CQRS with event sourcing is the best pattern for most use cases in the Kafka world:

Nevertheless, it is still only the second-best approach and is often an anti-pattern for streaming data.

reference : Request-Response in Kafka

(Appendix) Kafka 와 웹소켓

또한 유저가 회원가입을 했을 때, 그 결과를 받아야한다. 이 때 Server-Sent Event(SSE)방식으로 받는 방법이 있다.

Server-Sent Events (SSE) is a server push technology where clients receive automatic server updates through the secure http connection. SSE can be used in apps like live stock updates, that use one way data communications and also helps to replace long polling by maintaining a single connection and keeping a continuous event stream going through it. We used a simple Kafka producer to publish messages onto Kafka topics and developed a reactive Kafka consumer by leveraging Spring Webflux to read data from Kafka topic in non-blocking manner and send data to clients that are registered with Kafka consumer without closing any http connections. This implementation allows us to send data in a fully asynchronous & non-blocking manner and allows us to handle a massive number of concurrent connections. We’ll cover: •Push data to external or internal apps in near real time •Push data onto the files and securely copy them to any cloud services •Handle multiple third-party apps integrations

reference : Server Sent Events using Reactive Kafka and Spring Web flux