-
Notifications
You must be signed in to change notification settings - Fork 300
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 라이브러리 구현하기 - 3, 4단계] 코코닥(이승용) 미션 제출합니다. #541
Conversation
- TransactionManager 는 트랜잭션의 시작, 커밋, 롤백 등의 로직을 담당한다.
- DataSourceUtils 는 트랜잭션 동기화 기능을 사용하여, 같은 Connection 객체를 재사용할 수 있도록 한다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 코코닥
3, 4단계 구현해주신다고 고생많으셨습니다
코멘트 조금 남겼으니 확인부탁드려요 🙂
|
||
private final TransactionManager transactionManager; | ||
|
||
public TransactionTemplate(final TransactionManager transactionManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용하지않는 생성자인거 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
삭제하겠습니다!
TransactionSynchronizationManager.bindResource(dataSource, connection); | ||
final Connection connection = dataSource.getConnection(); | ||
if (TransactionManager.isTxBegin(dataSource)) { | ||
connection.setAutoCommit(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataSourceUtils에서
connection.setAutoCommit(false);
를 하는 이유가 무엇인가요?
트랜잭션을 사용하지 않는 부분도 전부 setAutoCommit(false)가 되는거같은데
transactionManager.begin();
시에 false 해야하지않을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DM 나눴던 내용으로 리팩터링 수행해보겠습니다!
} | ||
|
||
public static boolean isTxBegin(final DataSource dataSource) { | ||
final Boolean flag = isTxBegin.get().get(dataSource); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
connection.getAutoCommit();
메서드를 활용할수있을것같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 메서드가 있었군요...! 알려주셔서 감사합니다.
다만 문제가 됐던 지점이 있었는데, 해당 메서드를 사용하려면 파라미터로 넘어오는 DataSource 을 기반으로 Connection 을 찾아와야 합니다.
해당 부분은 DataSourceUtils.getConnection() 메서드를 사용해서 Connection 을 찾아올 순 있으나, 문제는 isTxBegin() 메서드가 public static 으로 열려 있기 때문에, 자칫 잘못 사용하면 새로운 Connection 객체를 새로 만들어서 가져오고, 그것에 대한 getAutoCommit() 을 사용하기 때문에.. 필요없는 성능 비용 지출이 생길 위험이 있었습니다.
때문에 현재 열려있는 트랜잭션이 존재하는가?
에 대한 판단을 효율적으로 하기 위해선, 트랜잭션이 시작됐을 때 그에 대한 flag 값을 어디엔가 캐싱해두는 작업이 필요합니다. 이를 위해서 threadLocal 변수로 따로 빼두었던 것인데, 생각해보니 트랜잭션이 시작됐을 때 그에 대한 flag 값
은 TransactionSynchronizationManager 에 있는 resources 변수를 통해 이미 관리가 되고 있었더라구요. (TransactionSynchronizationManager 내부 resources 맵 안에는 트랜잭션이 시작된 Connection 에 대해서만 저장하고 있기 때문에)
따라서 TransactionManager 내부의 ThreadLocal 변수를 삭제하고, 열려있는 트랜잭션이 존재하는가?
에 대한 판단 책임을 TransactionManager 에서 TransactionSynchronizationManager 로 옮겼습니다!
|
||
public abstract class TransactionSynchronizationManager { | ||
|
||
private static final ThreadLocal<Map<DataSource, Connection>> resources = new ThreadLocal<>(); | ||
private static final ThreadLocal<Map<DataSource, Connection>> resources = ThreadLocal.withInitial(HashMap::new); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withInitial 라는 메서드가 있었군요 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변경사항 확인했습니다~!
미션 하느라 고생하셨어요!
다음 미션도 화이팅 👍
안녕하세요 파워! 길었던 연휴도 이제 슬슬 끝나가네요. 파워는 컨디션 회복 많이 하셨나요?
이번 미션 구현이 제 우선순위에서 많이 밀려서 시간을 많이 못썼습니다 🥲
그래서 3, 4단계를 한번에 구현해서 제출하게 되었습니다 ㅠㅠ..
우선 3단계 요구사항이었던
로직의 원자성을 보장하기 위한 트랜잭션 적용
과, 4단계 요구사항이었던트랜잭션 동기화
,서비스 추상화
모두 만족시킨 것 같습니다.코드의 대략적인 흐름은 아래 그래프와 같습니다.
TransactionTemplate 은 트랜잭션을 적용하면서 발생하는 중복 로직을 제거하기 위해 만들어진 템플릿 콜백 클래스입니다.
TransactionManager 에서는 트랜잭션 시작, 커밋, 롤백 등을 담당하고 있습니다. 각 스레드 및 데이터소스에서 진행중인 트랜잭션이 존재하는지 확인해주기 위해 ThreadLocal 로 해당 상태를 관리해주기도 합니다.
DataSourceUtils 에서는 Connection 생성/파괴를 관리하는데, 진행중인 트랜잭션이 있다면 Connection 을 재활용할 수 있도록 도와줍니다.
추가로, 분산 트랜잭션이나 트랜잭션 전파에 대해서는 고려하지 않았습니다!
리뷰 잘 부탁드립니다!!