1. 나의 나눔
누적되는 추상화
일단 처음으로 쉽게 안 읽히더라구요. 예제 코드를 좀더 신중하게 작성해 보니 이해가 조금 더 되긴 했는데 추상화된 부분들이 계속 누적되다 보니까 잘 이해되지 않는 부분이 생기더라구요. 그래서 구체적으로 어떻게 동작한다고 주석으로도 치고 글로도 정리하니까 조금 더 이해에 도움이 되었던 것같습니다. 그래도 평소보다 읽는 속도가 느렸던 것 사실인 것 같습니다.
집요함
다읽지 못했지만 6장 읽으면서 스프링 프레임웍이 지향하는 더 나은 코드를 향한 집요함이 느껴지더라구요. 여기서 더 뭘하는거지? 싶으면 좀더 뭘 하고, 또 덜 뭐할 수 있지? 생각했는데 계속 뭘 더 하더라구요. 엔지니어링에 대한 이런 집요함에 대해 배울 수 있어서 좋았습니다.
과정과 결과
또 한편으로는 토비의 스프링 책읽으면서 이런 과정을 보는게 저는 되게 좋은데, 대게의 개발자들이 그냥 결과로써 탄생한 @Transactional 어노테이션 사용법을 간단히 알고 사용하는 경우가 많잖아요? 스프링이 아닌 특정 기술의 경우에는 내부 구현의 원리를 잘 모르면 문제가 되는 경우가 있는데 스프링은 책을 읽다보니 워낙 추상화가 잘되어 있는 것 같아서 이런 과정을 아는 것과 결과만 아는 것이 현장에서 어떤 크리티컬한 차이를 만들어 내는지 앞으로 차차 경험해 보고 싶다는 생각이 들었습니다.
쉽게 이해되는 뒷 부분들
지난주에 읽었던 AOP 앞 부분은 좀 어려웠는데 앞 부분의 과정을 어느 정도 이해하니 뒤에 나오는 결과를 응용하는 부분들이 점점 술술 읽혔던 것 같습니다.
데이터를 다루는 분야에 대한 호기심 자극
(그리고) 제가 개인적으로 일하면서 DB를 다루는 일을 해 본적이 없는데, 뒷 부분에서 트랜잭션 속성에 대해 다루면서 트랙잭션 전파나 격리수준 그리고 롤백 전략 같은 내용을 읽다보니 처음으로 순수하게 데이터를 다루는 일에 대한 호기심이 조금 생기더라구요. 그래서 이 책 끝까지 다 읽고 JPA 같은 지금 회사에서도 사용하고 있고 대중적인 기술을 좀더 공부해 봐야 겠다는 생각을 했구요.
2. 질문
트랜잭션 격리수준
트랜잭션 격리 수준에 대한 설명이 간단히 나오긴 하는데 조금 더 깊이 있게 이해하고 싶다는 생각이 들었어요. 기본적으로 디폴트 설정을 사용한다고 설명되고 있는데 혹시 어떤 케이스에는 디폴트 설정만으로 문제가 되는 경우가 있는지도 궁금하고, 이 트랜잭션 격리수준이란 걸 이해하는게 어느 정도 중요한 건지 좀 설명을 듣고 싶습니다. 제가 너무 잘 모르는 분야라 너무 설명히 장황히 필요한 내용이면 혹시 관련된 잘 정리된 책이나, 글이 있으면 조금 소개 받고 싶어서 질문드려 봅니다.
3. 모임중 인상깊은 말들 (1주차)
- 다른 형태의 객체간 인터페이스만 하는 DAO 같은 경우는 목을 만들어 보았자 큰 의미가 없는 경우도 있다.
- 데코레이터 패턴은 같은 인터페이스를 구현한 빈들을 구현해서 얼마든지 구현할 수 있다. 스프링의 DI를 그냥 활용해서 쓸 수 있다.
- JSON 인코딩, 디코딩 코드 개선 / 외부 API 서버 의존 / DB 의존 등이 정말 성능에 영향을 주지, 프록시를 통해 호출 하나 더 하는 것, 또는 바이트코드 삽입으로 클래스 로딩이 느는건 성능에 거의 영향이 없다고 봐도 좋습니다.
- 트랜잭션은 비지니스 로직 관점에서 일어나거나 일어나지 않거나 해야하는 일에 적용한다.
- DirtyRead 문제 - 커밋되지 않은 변경 사항이 보이는 문제.
- AOP가 메서드 단위로 이루어 지는데, 혹시 다른 단위로서 적용할 수 있는 방법이 있는가? (예를 들면 생성자, 파라미터?) JoinPoint에 대한 이이기이다. 스프링은 메서드 호출이 JoinPoint가 유일하다. 그러나 AspectJ 같은 걸 사용하면 더 다양한 JoinPoint 적용이 가능하다. 생성자 전후 프록시도 가능하다. public 프로퍼티에 접근할 떄도 Advice를 추가가능하다. synchronized 에도 Advice 추가가 가능하다. 굉장히 다양한 JoinPoint를 적용가능하다.
- JPA와 같은 외부 라이브러리에서 스프링빈이 아닌 객체에서 스프링 빈을 주입받고 싶은 경우에 AspectJ 생성자 조인 포인트 사용해서 응용하기도 한다.
- 트랜잭션이 적용되지 않는데 모르고 넘어가는 케이스가 간혹 존재하게 되는데 그런 문제 때문에 명시적으로 트랜잭션을 명시적으로 하자는 주의도 생기고 있다. AOP 사용에 대해 바르게 숙지해야 한다. 중요하다. 다음주에 한 번 다루어 보자.
4. 모임중 인상깊은 말들 (2주차)
- JPA는 엔티티와 DB 테이블 간의 매핑을 수행하는데 롤백 테스트를 사용하면 DB에 한번도 쿼리가 안날라가고 테스트가 성공으로 끝나는 경우가 발생한다. 만약 매핑에 문제가 있으면 쿼리를 날려봐야 문제가 드러난다. 그래서 JPA 사용하면 flush()에 대해서 확실히 공부하고 사용해야 한다.
- 스프링에서 트랜잭션 속성 관련해서 이런 설정하는게 있었어란 걸 기억하고 나중에 필요할 때 자세히 찾아보면서 적용해 볼 수 있겠어.
- 특정 파라미터를 포함하고 있는 메서드 포인트컷을 찾는 좋은 방법이 있는지 궁금합니다. 스프링이 AspectJ의 표현식만 도입했기 때문에 AspectJ 문서를 찾아보면 도움이 될 것 같다.
- 서비스라는 네이밍을 사용하면서 서비스 클래스의 응집성이 떨어지는 방향으로 나아갈 때가 있다. 그래서 조금더 구체적인 이름이 필요할 때도 있다.
- 구현클래스에서 Default, Base 등을 사용하는 경우도 있다.
- Service & ServiceImpl 예전부터 자바가 사용하던 이름 패턴이다.
- 트랜잭션이 롤백되는가 커밋되는가는 명확히 이해해야 한다.
- 프로젝트의 어느 단계에는 트랜잭션이 정말 잘 걸렸는가(커밋/롤백)를 한 번 쯤은 꼭 검증해야 한다.
- 체크 예외는 호출한 쪽에서 받아서 코드로 어떤 복구 작업을 할 수 있는 경우 사용할 것 같습니다. 그래서 개발자가 이것을 고민하게 만드는 거죠.
- 명시적인 예외는 요즘 자바에서 Optional을 명확히 써서 코드 흐름이 명확히 보이도록 많이 하는 것 같다.
- AOP를 적용한 트랜잭션 외의 다른 응용이 궁금하다. → 보안과 로깅이 있는 것 같다.
- AOP가 좋은게 넣었다가 그냥 뺄 수도 있어서 좋다.
- 토비의 스프링을 통해 테스트 코드 작성에 대해 많이 배운 것 같다.
- aop, tx 스키마 네임스페이스를 대체할 방법이 XML 사용 없이 할 수 있는 방법이 없어 막막했다.
- 인풋과 아웃풋을 확신하더라도 아웃풋이 기대결과와 다르면 내부 구현에 뭔가 문제가 있는거니까 디버거로 간단히 따라가면서 문제를 찾아볼 수 있는 것 같습니다.
- 타이밍이 중요한 케이스라면 디버거로 문제를 못찾기 때문에 로깅을 통해 하기도 한다. 극한의 경우에는 로깅 타이밍 때문에도 버그가 사라지거나 생기기도 한다.
- 다른 프레임워크 언어드에서는 AOP라는 용어 자체보다, 데코레이터나 프록시 패턴을 활용하는 접근방법은 다양하게 존재할 것이다.
- 스프링 AOP 주의사항 있을까?
- private 메서드에 접근이 안된다.
- 타겟에서 타겟 호출 시 안된다.
- final 클래스 사용할 수 없다.
- 인터페이스 없이 사용하는 경우 생성자가 두번 호출되는 문제
5. 참고