스프링 347

29. 스프링 부트 자동 리소스 등록

스프링 부트가 자동으로 등록해 주는 게 꽤 많이 있다. 그 중 DataSource 이름 : dataSource 이것도 자동으로 등록된다. 물론 개발자가 직접 DataSource를 빈으로 등록하면 이 기본은 등록되지 않는다. 근데 우리가 이거 등록할 때는, URL, 아이디, 패스워드 이런 거 다 넣어 줬었다. 근데, 자동으로 등록할 때에는 이런 정보들을 application.properties에 쓰면 된다. spring.datasource.url=jdbc:h2:tcp://localhost/./test spring.datasource.username=sa spring.datasource.password=1234 물론, 기타, 커넥션 풀 관련 설정이라던지도 저기다 쓰면 된다. 만약 url을 명시하지 않았다면,..

27. 트랜잭션 AOP

AOP는 관점 지향 프로그래밍 이라고 해서.. https://qwefdg3.tistory.com/89 좀 그러니까 공통사항들? 그런 거 처리하는 건데. 지금은 Proxy를 통해서 공통사항들을 처리한다고 한다. 딱 트랜잭션을 위해 스프링에서 제공해주는 애노테이션이 있다. @Transactional이다. 이거 붙으면 뭐 아래 비즈니스 로직을 트랜잭션의 한 부분 예를 들어 TransactionStatus status = transactionManager.getTransaction(..); try{ 로직 commit(); }catch(e){ rollback(); throw new RuntimeException(e); } 저 로직부분에 넣어준다는 그런 소리 인 것 같다. 우선 프록시 도입 전 을 보자. 직접 순수..

26. 트랜잭션 템플릿

보다보면, 같은 패턴이 반복되는 것이 있다. try.. catch.. 커넥션 얻고, 상태 얻고 등 public void accountTransfer(String fromId, String toId, int money) throws SQLException { TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try{ transferLogic(fromId, toId, money); transactionManager.commit(status); }catch(Exception e){ transactionManager.rollback(status); throw new IllegalState..

25. 트랜잭션 매니저

저번 코드는 DB와 소통하는 리포지토리의 커넥터가 서비스까지 올라왔고, 그로 인해 서비스가 특정 기술에 영향을 받게 되었다. 서비스는 특정 기술에 의존 하면 안된다. 그러므로 트랜잭션 추상화에 대해 생각해 보았다. 편리하게도, 이미 스프링이 트랜잭션에 대한 인터페이스를 제공해 주고, 각 회사들이 구현체를 만들어 놨다. 이제 실제로 코드로 사용 해 볼 것이다. @Slf4j public class MemberRepositoryV3 { private final DataSource dataSource; public MemberRepositoryV3(DataSource dataSource) { this.dataSource = dataSource; } public Member save(Member member) t..

24. 트랜잭션 동기화

스프링이 제공하는 트랜잭션 매니저( PlatformTransactionManager )는 크게 2가지 역할을 한다. 트랜잭션 추상화 리소스 동기화 트랜잭션 추상화는 직전에 말 했고, 리소스 동기화 트랜잭션을 유지하려면 트랜잭션의 시작부터 끝까지 같은 커넥션(DB세션)을 유지해야 한다. 이전에는 그걸 파라미터로 줬다. 하지만 스프링이 제공하는 트랜잭션 매니저는 이런 식이다. 트랜잭션 매니저 내부에는 트랜잭션 동기화 매니저가 있다. 트랜잭션 할 때는 커넥션을 쓰레드 로컬에 저장해 놓는데, 쓰레드 로컬이란 그 쓰레드만 접근할 수 있는 저장소이다. 트랜잭션 동기화 매니저가 쓰레드 로컬에 저장해 놓는 것이다. 그래서 커넥션이 필요하면 저 로컬쓰레드에 있는 커넥션을 획득하면 되서, 이전처럼 파라미터로 커넥션을 전달..

23. 트랜잭션 추상화

스프링은 서비스 계층을 순수하게 유지하면서, 앞서 말했던 문제들을 해결 할 수 있는 다양한 방법과 기술들을 제공한다. 먼저, 앞서 Service는 Jdbc 기술에 의존하고 있었다. 만약 Jpa로 바꾸게 된다면, Jpa의 트랜잭션 구현은 비슷한 면도 있지만 다르다. 만약 기술을 바꿀 때 마다.. 리포지토리는 사실 DB와의 소통을 위한 것 이라 적어도 명분은 되지만, 비즈니스 로직은 아니다.. 정말 순수해야 한다. DB 접근 기술에 따라 서비스 로직도 바꿔야 한다면, 리포지토리의 단일책임 원칙에 맞지 않는 것이다. 해결법 중에 이제, 트랜잭션 인터페이스를 만들고, 트랜잭션은 외부에서 주입받거나, 어댑터 패턴으로 처리하고 하면 되긴 할 듯 싶다.(확실히 이번 경우는 서버사이드에서 바뀌는 거니 어댑터 패턴은 아..

22. 기존 트랜잭션의 문제

먼저, 스프링의 애플리케이션 구조 Controller에서 사용자와 상호작용 하고 Controller에서 사용자의 요청에 따라 알맞은 서비스를 호출하고 서비스에서는 필요에 따라 리포지토리(DB)에 접근한다. Controller UI 관련 처리 웹 요청, 응답 사용자 요청 검증 Service 비즈니스 로직 가급적 특정 기술에 의존하지 않고 순수 자바 코드로 작성 Repository DB와 소통하는 코드 여기서 Service는, 특정 기술에 종속적이지 않아야 한다. 웹, REST API 등 여러 통신 방법에도 같아야 한다. 그래서 거의 순수 자바 코드로 작성되어야 한다. Controller에서는 웹, REST API 등 다양한 요청 및 응답은 이 친구가 처리를 해 주고, 그래서 요청마다 약간 다를 수 있고, ..

21. 이체 트랜잭션 적용

우선, 커밋모드에 대한 적용은 세션마다 이므로, 커넥션을 얻는 것은 한 섹션을 생성한 다음 그 섹션과의 소통을 위한 객체를 얻는 것이니 우리가 커넥션을 지정해서 줄 필요가 있다. @Slf4j public class MemberRepositoryV2 { private final DataSource dataSource; public Member findById(Connection con, String memberId) throws SQLException { String sql = "select * from member where member_id = ?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = con.prepareStateme..