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단계] 다즐(최우창) 미션 제출합니다. #566

Merged
merged 4 commits into from
Oct 9, 2023

Conversation

woo-chang
Copy link
Member

안녕하세요 헙크 ㅎㅎ 벌써 마지막 미션이네요 🥲
요즘 따라 시간이 정말 빠르다고 느껴지는데 헙크는 어떠신가요?

4단계에서는 요구사항을 바탕으로 아래 사항들을 학습하고 구현해보는 시간을 가졌습니다!

  1. DataSourceUtils를 사용하는 TransactionSynchronizationManager 구현
  2. 트랜잭션 서비스 추상화
  3. 현재 트랜잭션이 존재하는지 여부 저장
    • JdbcTemplate에서도 DataSourceUtils 메서드를 사용하게 되는데, 이때 트랜잭션 여부를 확인할 수 없으면 트랜잭션이 종료되지 않았음에도 커넥션 자원을 회수하기에 커밋 시 이미 회수된 자원에 대한 예외가 발생하게 됩니다. 따라서 트랜잭션이 걸려 있으면 자원을 회수하지 않도록 구현하였습니다.
  4. JdbcTemplate에서 TransactionManager 의존성 제거
    • 기존에는 커넥션 획득과 자원 회수를 위해 TransactionManager 의존성을 가지고 있었지만, DataSourceUtils를 구현함에 따라 해당 메서드를 활용하면 되기에 원래대로 DataSource 의존성만 가지고 있도록 수정하였습니다.

마지막 미션 리뷰도 잘 부탁드립니다 🙇🏻‍♂️

@woo-chang woo-chang self-assigned this Oct 9, 2023
Copy link
Member

@HubCreator HubCreator left a comment

Choose a reason for hiding this comment

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

dazzle!! 이번에도 깔끔한 코드 잘 봤습니다. 내일 또 제가 개인 일정이 있어서 지금 approve하지 않으면 차질이 생길 것 같네요 ㅎㅎㅎ 그래도 코멘트에서 다즐의 의견을 듣고 싶은 부분을 남겨 놨으니 한 번 얘기해보도록 합시다! 이번 미션 너무 고생하셨습니다 :)


public abstract class TransactionSynchronizationManager {

private static final ThreadLocal<Map<DataSource, Connection>> resources = new ThreadLocal<>();
private static final ThreadLocal<Map<DataSource, Connection>> resources = withInitial(HashMap::new);
private static final ThreadLocal<Boolean> actualTransactionActive = withInitial(() -> false);
Copy link
Member

Choose a reason for hiding this comment

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

쓰레드 로컬에서 이런 초기화 함수도 지원해주는군요!

Copy link
Member Author

Choose a reason for hiding this comment

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

저도 이번에 ThreadLocal을 적용해 보면서 알게 되었습니다 :)

Comment on lines +23 to +26
transactionTemplate.execute(() -> {
userService.insert(user);
return null;
});
Copy link
Member

Choose a reason for hiding this comment

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

return값이 없는 경우를 위한 TransactionTemplate 메서드를 만들면 어떨까요?!

Copy link
Member Author

Choose a reason for hiding this comment

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

만들지 말지 고민했었는데 꼼꼼하게 집어주셨네요 ㅎㅎ

말씀해주신 것처럼 return 값이 필요로 하지 않을 때 사용할 수 있는 메서드가 있으면 좋을 것 같아요 👍

T result = action.doInTransaction();
transactionManager.commit();
transactionManager.doCommit();
return result;
} catch (RuntimeException | Error e) {
Copy link
Member

Choose a reason for hiding this comment

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

확실히 Error인 상황에도 롤백이 될 수 있도록 처리하면 좋겠네요! Error를 catch하여 뭔가 의미 있는 행동을 하는 케이스를 여기서 처음 본 것 같네요 ㅋㅋㅋㅋ

Copy link
Member Author

Choose a reason for hiding this comment

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

스프링에서도 Error인 상황에서는 롤백되도록 처리해주고 있더라구요 😀

프레임워크를 학습하며 최대한 따라갈 수 있도록 구현해보았습니다 !

Comment on lines +31 to +33
if (TransactionSynchronizationManager.isActualTransactionActive()) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

외부에서 setActualTransactionActive값을 false로 변경해주어야만 커넥션 자원이 반환되는군요. 이렇게 구현하신 이유가 궁금합니다! releaseConnectinon을 호출하면 바로 자원을 반환하도록 하는 것과 어떤 차이가 있나요?! 당장에 잘 떠오르지가 않네요 ㅎㅎㅎ

Copy link
Member Author

Choose a reason for hiding this comment

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

우선 트랜잭션이 살아있는동안은 커넥션을 공유하고 있는 상태라고 판단했어요 🤓

TransactionTemplate만으로 데이터베이스와의 모든 상황을 처리한다며 해당 요소를 판단하지 않아도 될 것 같아요. 항상 TransactionManager에 의해 커넥션 자원이 회수되기 때문입니다.

하지만 단순히 JdbcTemplate를 사용하는 경우에는 메서드마다 커넥션을 반환해주는 작업을 수행합니다. 이때 트랜잭션 범위에 있다면 커넥션을 회수하지 않아야 다음 SQL에서도 같은 커넥션을 공유할 수 있게 됩니다. 이를 판단하지 않고 JdbcTemplate에서 커넥션을 회수해버린다면 TransactionManager에서 커넥션을 다 사용하고 close할 때 이미 close된 커넥션이라는 예외 메시지를 만나게 됩니다.

따라서 트랜잭션이 존재하는 동안은 TransactionManager를 통해 connection 자원이 회수되어야 하기 때문에 커넥션 회수 작업을 수행하지 않도록 하였습니다 !

Copy link
Member

@HubCreator HubCreator left a comment

Choose a reason for hiding this comment

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

dazzle!! 이번에도 깔끔한 코드 잘 봤습니다. 내일 또 제가 개인 일정이 있어서 지금 approve하지 않으면 차질이 생길 것 같네요 ㅎㅎㅎ 그래도 코멘트에서 다즐의 의견을 듣고 싶은 부분을 남겨 놨으니 한 번 얘기해보도록 합시다! 이번 미션 너무 고생하셨습니다 :)

@HubCreator HubCreator merged commit 18da6a6 into woowacourse:woo-chang Oct 9, 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