Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

포인트 지급 로직 어떻게 처리할까? 직접 메소드 호출 vs 이벤트 #8

Open
Yiseull opened this issue Jan 25, 2024 · 3 comments
Assignees

Comments

@Yiseull
Copy link
Owner

Yiseull commented Jan 25, 2024

📍 상황

LIME 서비스 개발 중에, 특정 상황에서 사용자에게 포인트를 지급하는 요구사항이 있었다. 포인트는 댓글 작성, 댓글 채택, 리뷰 작성 세 가지 상황에서 지급된다.

현재 LIME 서비스에서는 이 로직을 AOP로 구현하고 있다. AOP는 주로 비지니스 로직과 그 외 공통 로직을 분리하는 프로그래밍 방식으로 사용되는데, 포인트 지급이라는 비지니스 로직을 AOP로 처리하는 것이 다소 어색해 보였다.

따라서, 이 기능을 '직접 메소드 호출' 또는 '이벤트 처리' 중 어느 방식으로 변경할지 고민하게 되었다.


📍 고려 사항

1. 관심사의 분리

포인트 지급이 비지니스 로직의 한 부분이라는 건 분명하다. 그렇다면 이 로직은 포인트 지급이 발생하는 로직(댓글 생성, 댓글 채택, 리뷰 생성)과 분리되어야 하는 관심사인가?

관심사를 분리하는 것이 맞는 것 같다. 예를 들어, 댓글 작성 로직을 고려해보면, 댓글 생성 시 포인트도 함께 지급된다. 이는 SOLID 원칙 중 하나인 '단일 책임 원칙(SRP)'을 위반하는 것이다. 만약, 지급 포인트가 3점에서 5점으로 변경될 경우, 댓글 생성 로직에도 영향을 미친다.

포인트 지급이 필요한 상황은 댓글과 리뷰 도메인에서 발생하지만, 실제 포인트 지급 처리는 회원 도메인에서 이루어진다. 만약 직접 메소드를 호출하면, 댓글과 리뷰 서비스는 회원 서비스에 대한 의존성을 주입 받아야 한다. 이로 인해 댓글/리뷰 서비스와 회원 서비스 간의 강한 의존성이 생겨난다. 또한, 이렇게 되면 댓글과 리뷰 서비스에서 각각 포인트 지급 로직을 중복해서 작성해야 하는 문제가 발생한다.

이벤트를 사용하면, 지급 포인트가 변경되더라도 댓글 생성 로직에 영향을 끼치지 않는다. 또한 도메인 간의 의존성을 분리함으로써 재사용성을 높일 수 있다. 이는 각 도메인의 책임을 명확히 분리하고, 유지 보수성을 높인다.

👉 이런 이유들로, 직접 메소드를 호출하는 것보다 이벤트를 사용하여 처리하는 방식을 선택하기로 결정했다.

2. 트랜잭션

포인트 지급이 발생하는 로직(댓글 생성, 댓글 채택, 리뷰 생성)과 포인트 지급 로직은 같은 트랜잭션에 포함되어야 하는가?

처음에는 각 로직이 다른 트랜잭션에 포함되어야 한다고 생각했다. 이유는 포인트 지급이 롤백될 경우, 댓글 생성 로직이 함께 롤백되지 않아야 한다는 생각에서였다.

그러나 우리 서비스를 고려해보면, 포인트는 사용자의 레벨을 표현하며, 이 레벨은 서비스에서 사용자의 전문성을 나타내는 중요한 수단이다. 따라서, 이 레벨을 높이는데 필요한 포인트는 서비스의 중요한 요소라고 볼 수 있다.

만약 사용자가 댓글을 작성했음에도 불구하고 포인트를 지급하지 않는다면, 이는 사용자에게 좋지 않은 경험을 제공하는 것이 될 것이다. 포인트 지급이 롤백되면, 댓글 생성 또한 함께 롤백되어야 하며, 사용자는 다시 댓글을 작성하도록 유도해야 한다.

👉 결국, 로직을 동일한 트랜잭션에서 처리할 것인지, 다른 트랜잭션에서 처리할 것인지 결정하는 것은 서비스를 고려하여 결정해야 한다.

@Yiseull Yiseull added the Spring label Jan 25, 2024
@Yiseull Yiseull changed the title 포인트 지급 로직 어떻게 처리할까? 변경 감지 vs 이벤트 포인트 지급 로직 어떻게 처리할까? 직접 메소드 호출 vs 이벤트 Jan 25, 2024
@Yiseull
Copy link
Owner Author

Yiseull commented Jan 25, 2024

@Yiseull
Copy link
Owner Author

Yiseull commented Jan 30, 2024

포인트 지급 로직을 Event로 처리한 후, 팀원에게 "여기에 비동기처리는 필요 없을까요?" 라는 리뷰를 받았다.

image


나는 비동기 처리할 경우 별도의 스레드로 실행되어 다른 트랜잭션에서 실행될 뿐, 더 자세한 내용은 몰랐는데 팀원이 TransactionSynchronizationManager 를 알려주었다. TransactionSynchronizationManager은 트랜잭션의 정보를 ThreadLocal로 관리하여 동일 스레드 내에서 트랜잭션의 동기화를 도와주는 트랜잭션 동기화 매니저이다.

정리하면 아래와 같다.

1. 비동기로 처리하게 되면 별도의 스레드에서 트랜잭션 실행
2. TransactionSynchronizationManager는 스레드마다 독립적으로 Connection을 관리하기 때문에 다른 스레드는 같은 트랜잭션 사용 불가능
=> 비동기 처리 불가능

@Yiseull
Copy link
Owner Author

Yiseull commented Feb 17, 2024

이 내용을 블로그에 옮겨 적었다! 😁
https://yiseull.tistory.com/31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant