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

[JDBC 라이브러리 구현하기 - 4단계] 테오(최우성) 미션 제출합니다. #517

Merged
merged 17 commits into from
Oct 10, 2023

Conversation

woosung1223
Copy link
Member

@woosung1223 woosung1223 commented Oct 8, 2023

안녕하세요~

망고랑 함께하는 마지막 PR이네요..🥲 이번에도 잘 부탁드립니다!

이번 단계에서는 요구사항에 맞춰 TransactionSynchronizationManager 를 통해 DataSource 별 커넥션을 관리하고, TransactionUserService라는 프록시 객체를 인터페이스 기반으로 생성했습니다.

DataSourceUtils를 통해 커넥션을 관리하면서 Transaction을 통해 트랜잭션 자체를 제어할 수 있도록 추상화 레벨에 따라 책임을 분리했습니다.

다만 이게 좋은 구조인지는 확신이 안들어서, 망고는 트랜잭션을 다루는 부분에서 어떤 식으로 객체를 분리했는지 이야기 들어보고 싶어요!

이번에도 망고의 날카로운 피드백 기다리겠습니다!!

아래는 전체적인 흐름을 나타낸 그림인데, 리뷰하실 때 참고하시면 좋을 것 같아요~ 🙇‍♂️ 감사합니다!
image

@woosung1223 woosung1223 self-assigned this Oct 8, 2023
Copy link

@Go-Jaecheol Go-Jaecheol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 테오
마지막 4단계까지 정말 고생하셨습니다!

이번에도 제가 생각 못한 부분까지 잘 구현해주셔서 오히려 제가 더 많이 배워갑니다 🙇‍♂️

크게 수정할 부분은 없고 질문에 대한 답변이랑 몇 가지 코멘트만 남겨놨는데,
이 부분들은 반영 안하셔도 되지만 그래도 마지막이기도 하고 의견 들어보고 싶으니 RC 한 번 드립니다 :)

Comment on lines 10 to 14
private static final ThreadLocal<Map<DataSource, Connection>> resources = new ThreadLocal<>();

private TransactionSynchronizationManager() {}
static {
resources.set(new HashMap<>());
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 리뷰 받으면서 알게 됐는데 withInitial이라는 ThreadLocal 생성에 대한 정적 팩토리 메서드가 있더라구요!

private static final ThreadLocal<Map<DataSource, Connection>> resources = ThreadLocal.withInitial(HashMap::new);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 정적 팩토리 메소드가 있는지 처음 알았네요! 적용했습니다 👍

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataSourceUtils를 통해 커넥션을 관리하면서 Transaction을 통해 트랜잭션 자체를 제어할 수 있도록 추상화 레벨에 따라 책임을 분리했습니다.

다만 이게 좋은 구조인지는 확신이 안들어서, 망고는 트랜잭션을 다루는 부분에서 어떤 식으로 객체를 분리했는지 이야기 들어보고 싶어요!

저는 객체 분리를 따로 진행하지 않아서 크게 얘기할 거리가 없네요 🥲

객체 분리를 진행하지 않고 서비스단에서 바로 처리하도록 했습니다.
테오의 코드에서 보자면 TransactionExecutor에서 Transaction 객체를 따로 생성하지 않고, 상황에 따라 connection.setAutoCommit(false); connection.commit(); 등 connection을 다루면서 트랜잭션 처리를 했습니다!

'이건 트랜잭션 처리를 위한 메서드야' 라고 책임을 명확히 해준다는 점에서 테오 코드처럼 객체를 분리하는 것도 좋아보이네요.
배워갑니다 🙇‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다!

그런데 생각해보니 망고 방식처럼 서비스에서 Connection 객체를 그대로 사용하는 것도 좋아보이네요!
지금은 별다른 처리도 해주고 있지 않기 때문에 Connection을 그대로 Service에서 다루는게 비용 측면에서 합리적이라고 생각합니다.

스프링의 경우에는 PlatformTransactionManager를 사용해서 아마 지금 저의 Transaction 객체와 비슷한 역할을 수행할텐데, 조금 더 알아봐야겠네요! 🤔

Comment on lines +42 to +46
private static class TransactionExecutor {

private DataSource dataSource;
private boolean readOnly = false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금은 TransactionUserService에서만 사용하고 있는데, 다른 서비스에서도 사용한다면 클래스를 분리해도 괜찮을 것 같아요 :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동감합니다 ㅎㅎ

지금은 사용처가 한 곳 뿐이라 응집도를 높이기 위해 이너 클래스를 사용했는데,
나중에 사용처가 늘어난다면 망고 말씀처럼 별도의 객체로 분리하는게 좋아보이긴 하네요!

Comment on lines +10 to +19
### step 4 기록
- 트랜잭션 동기화 매니져는 왜 Map 형태로 구현이 되어 있을까?
- ThreadLocal의 경우 하나의 스레드에 대한 지역변수처럼 작동한다.
- 그렇다면 Map을 사용하는 이유는 하나의 서비스에서 여러 DataSource를 사용할 일을 대비하기 위함이 아닐까?

- 스프링을 사용하지 않는 환경에서 Spring AOP 같은 기능은 어떻게 만들 수 있을까?
- 동적으로 런타임에 프록시를 만들고 싶다.
- 스프링의 경우 Context로 빈들을 관리하기 때문에 런타임 주입 시 프록시 객체로 주입할 수 있다.
- 하지만 스프링을 사용하지 않는 경우에는 `new 객체();` 처럼 선언을 하니 런타임에 프록시로 구현체를 갈아끼울 수 없다.
- 객체간 의존관계를 스프링이 설정한다는 점 덕분에 Spring AOP가 가능한게 아닐까?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

항상 제가 생각 못한 부분까지 깊게 고민하시는 군요.. 제가 리뷰이가 된 기분입니다 🤣

Copy link

@Go-Jaecheol Go-Jaecheol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

마지막까지 고생하셨어요 테오 😎

이번 미션은 여기서 마무리 할게요!

2주 동안 재밌었습니다 :)

@Go-Jaecheol Go-Jaecheol merged commit f0d65a3 into woowacourse:woosung1223 Oct 10, 2023
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants