만약 서비스 계층이 JDBCRepository 구현체에 의존하고 있는 상황에서, 향후 JPA와 같은 다른 데이터 접근 기술로 변경하면 서비스 계층의 트랜잭션 관련 코드도 모두 변경해주어야 합니다.JDBC 트랜잭션 의존JDBC -> JPA로 변경이 문제를 해결하기 위해서는 트랜잭션 기능을 추상화하면 됩니다. 단순하게 생각해보면 아래와 같이 인터페이스를 만들어서 사용하면 될 것 입니다.public interface TxManager { begin(); commit(); rollback();}트랜잭션 추상화와 의존관계서비스는 특정 트랜잭션 기술에 직접 의존하는 것이 아니라, TxManager라는 추상화된 인터페이스에 의존하고 있습니다. 이제 원하는 구현체를 DI를 통해서 주입받기만 하면 되는데..
세션1이 트랜잭션을 시작하고 데이터를 수정하는 동안 아직 커밋을 수행하지 않았는데, 세션2에서 동시에 같은 데이터를 수정하게 되면 여러가지 문제가 발생한다. 만약 세션1이 중간에 롤백을 하게 되면 세션2는 잘못된 데이터를 수정하는 문제가 발생한다.이런 문제를 방지하려면, 세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에는 커밋이나 롤백 전까지 다른 세션에서 해당 데이터를 수정할 수 없게 막아야 한다. 여기서는 데이터베이스 Lock을 이용하여 이 문제를 해결하는 방법을 알아보겠다.세션1은 memberA의 금액을 500원으로 변경하고 싶고, 세션2는 같은 memberA의 금액을 1000원으로 변경하고 싶다. 데이터베이스는 이런 문제를 해결하기 위해 락(Lock)이라는 개념을 제공한다.세션1은 트랜잭션을 시..
데이터베이스 연결 구조사용자는 웹 애플리케이션 서버(WAS)나 DB 접근 툴 같은 클라이언트를 사용해서 데이터베이스 서버에 접근할 수 있다. 클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게 되는데, 이때 데이터베이스 서버는 내부에 세션이라는 것을 만든다. 이후 커넥션을 통한 모든 요청은 이 세션을 통해 실행된다.개발자가 클라이언트를 통해 SQL을 전달하면 현재 커넥션에 연결된 세선이 SQL을 실행한다. 세션은 트랜잭션을 시작하고, 커밋 또는 롤백을 통해 트랜잭션을 종료한다. 사용자가 커넥션을 닫거나, 세션을 강제로 종료하면 세션이 종료된다.커넥션 풀이 10개의 커넥션을 생성하면, 세션도 10개가 만들어진다.트랜잭션 개념 이해하기아래 예제(격리 수준: READ_COMMITED)는 트랜잭션 개..
커넥션을 획득하는 다양한 방법DriverManager를 통해 커넥션 획득커넥션을 얻는 방법은 JDBC DriverManager 를 직접 사용하거나, 커넥션 풀을 사용하는 등 다양한 방법이 존재한다.DriverManager를 통해 커넥션 획득하다가 커넥션 풀로 변경시 문제만약 DriverManager를 통해서 커넥션을 획득하다가, 커넥션 풀을 사용하는 방법으로 변경하려면 어떻게 해야할까? 예를 들어 애플리케이션 로직에서 DriverManager 를 사용해서 커넥션을 획득하다가 HikariCP 같은 커넥션 풀을 사용하도록 변경하면 커넥션을 획득하는 애플리케이션 코드도 함께 변경해야 한다. 의존관계가 DriverManager에서 HikariCP로 변경되기 때문이다. 그리고 둘의 사용법도 조금씩 다를 것이다.커..
데이터베이스 커넥션을 획득할 때는 다음과 같은 복잡한 과정을 거친다.애플리케이션 로직은 DB 드라이버를 통해 커넥션을 조회한다.DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다. 물론 이 과정에서 3 way handshake 같은 TCP/IP 연결을 위한 네트워크 동작이 발생한다.DB 드라이버는 TCP/IP 커넥션이 연결되면 ID, PW와 기타 부가정보를 DB에 전달한다.DB는 ID, PW를 통해 내부 인증을 완료하고, 내부에 DB 세션을 생성한다.DB는 커넥션 생성이 완료되었다는 응답을 보낸다.DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다.이렇게 커넥션을 새로 만드는 것은 복잡하고 시간도 많이 소모되는 일이다. DB는 물론이고 애플리케이션 서버에서도 TCP/IP 커넥션을 새로 생성하기..
JDBC 등장 계기일반적으로 애플리케이션을 개발하면 중요한 데이터는 대부분 데이터베이스(RDB, NoSQL)에 보관한다.클라이언트가 애플리케이션 서버를 통해 데이터를 저장하거나 조회하면, 애플리케이션 서버는 다음 과정을 통해 데이터베이스를 사용한다.커넥션 연결: 주로 TCP/IP를 사용해서 커넥션을 연결한다.SQL 전달: 애플리케이션 서버는 DB가 이해할 수 있는 SQL을 연결된 커넥션을 통해 DB에 전달한다.결과 응답: DB는 전달된 SQL을 수행하고 그 결과를 응답한다. 애플리케이션 서버는 응답 결과를 활용한다.여기서 발생할 수 있는 문제는 각각의 데이터베이스마다 커넥션을 연결하는 방법, SQL을 전달하는 방법, 그리고 결과를 응답 받는 방법이 모두 다르다는 점이다. 여기서 발생할 수 있는 문제는 크..
spring security는 쓰레드로컬 기반으로 동작하기 때문에 reactive 환경에서는 사용하기 힘들다. 그렇다면 reactive 환경에서는 security를 사용하지 않는걸까? 이번에는 reactive 환경에서 security를 어떻게 사용하는지 알아보자.SecurityFilterChainservlet stack에서는 Servlet Filter를 사용하는데, Filter Chain 중간에 DelegatingFilterProxy를 추가하고, DelegatingFilterProxy는 내부적으로 여러 개의 Security Filter를 갖는 SecurityFilterChain을 호출한다.FilterChain내에서는 bean을 사용하기 힘들지만, SecurityFilterChain은 Spring Cont..
RestTemplate기존에 사용하던 RestTemplate은 동기 blocking 기반의 webClient이다. 스프링 5.0부터 더이상의 개발은 하지 않고 유지만 하고 있으며, WebClient를 사용하길 권장하고 있다.WebClientWebClient는 Non-blocking reactive http 클라이언트이며, thread safe하기 때문에 여러 쓰레드에서 동시에 접근해도 문제가 없다. Reactor Netty, Jetty, apache의 HttpComponent를 이용해서 구현되어 있고, http 호출을 위한 여러 설정들을 메서드 체이닝을 통해 유연하게 설정할 수 있다는 특징이 있다.WebClientBuilderWebClientBuilder는 WebClient를 만들면서 필요한 설정들을 제..
Functional Endpoints는 스프링 5.x 버전부터 추가된 기능이다.기존에 Controller를 기반으로 웹서버를 구성하던 것과는 다르게 Functional Endpoints를 사용하면 HandlerFunction과 RouterFunction를 이용해서 좀 더 함수형 기반으로 웹서버를 구성할 수 있다.HandlerFunctionHandlerFunction은 요청을 처리하고, 응답을 반환한다.handle: ServerRequest를 인자로 받고 ServerResponse를 Mono로 반환하는 추상 메서드RouterFunctionRouterFunction은 path, method, predicate등으로 handlerFunction과 연결하여 해당 요청이 들어왔을 때, handlerFunction..
DispatcherHandlerDispatcherHandler는 WebHandler를 구현하고 있고, handlerMappings, handlerAdapters, resultHandlers로 구성되어 있다.DispatcherHandler의 요청 처리 흐름DispatcherHandler에서 요청을 처리하는 흐름을 도식화하면 아래와 같이 나타낼 수 있다.Netty로부터 요청(request)이 들어온다.DispatcherHandler는 HandlerMapping List를 순회하면서 요청을 처리할 수 있는 Handler를 찾아 반환한다.Handler의 호출을 위임하기 위해 HandlerAdapter List로 가서 이 요청을 처리할 수 있는 HandlerAdapter를 조회한다.반환받은 HandlerAdapt..
- Total
- Today
- Yesterday
- 백준
- Spring
- 코틀린
- MySQL
- 스프링
- 코테
- 그리디
- 인프런
- mysql 8.0
- 노마드코더
- 릿코드
- kotlin
- Real MySQL
- 파이썬
- 노마드
- 자료구조
- 알고리즘
- Algorithm
- 구현
- 정렬
- spring boot
- 리팩토링
- 스프링부트
- 북클럽
- 스프링 부트
- 문자열
- webflux
- 데이터베이스
- leetcode
- 김영한
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |