스프링과 문제 해결 순수한 서비스 계층 서비스 계층은 특정 기술에 종속적이지 않게 개발해야 한다. 계층을 나눈 이유도 서비스 계층을 최대한 순수하게 유지하기 위한 목적이 크다. 즉, 한 마디로 JDBC를 쓰다 JPA로 변경, Http API를 쓰다가 GRPC로 변경 등에 대한 과정으로 인해 서비스 계층에 수정이 있으면 안된다. 스프링은 트랜잭션 문제 (JDBC에 의존하는 문제, 트랜잭션 동기화, 반복 문제), 예외 누수 등의 문제를 해결할 수 있는 다양한 방법을 제공한다. 트랜잭션 추상화 트랜잭션은 원자적 단위의 비즈니스 로직을 처리하기 위해 사용한다. JDBC, JPA 등 구현 기술마다 트랜잭션을 사용하는 방법이 다르다. (JDBC : setAutoCommit(false), JPA : transacti..
트랜잭션 개념 이해 트랜잭션은 이름 그대로 번역하면 거래라는 뜻이다. 즉, 데이터베이스에서 트랜잭션은 하나의 거래를 안전하게 처리하도록 보장해주는 것을 의미한다. 데이터를 저장할 때 파일 저장이 아닌, 데이터베이스에 저장하는 이유 중 대표적인 이유는 트랜잭션을 지원하기 때문이다. 하나의 트랜잭션이 모두 성공해서 데이터베이스에 반영되는 것을 커밋이라하고, 작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 롤백이라 한다. 트랜잭션 ACID 트랜잭션은 원자성(Atomicity), 일관성 (Consistency), 격리성(Isolation), 지속성(Durability)를 보장해야 한다. 원자성 : 트랙잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 실패해야 한다. 일관성 : 모든 ..
커넥션 풀 이해 데이터베이스 커넥션 획득 과정 애플리케이션 로직은 DB 드라이버를 통해 커넥션을 조회한다. DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다. (3 way handshake 등) DB 드라이버는 TCP/IP 커넥션이 연결되면 ID, PW등 필요한 부가 정보를 DB에 전달한다. DB는 ID,PW를 통해 내부 인증을 완료하고, 내부에 DB 세션을 생성한다. DB는 커넥션 생성이 완료되었다는 응답을 받는다. DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다. 이렇게 커넥션을 새로 만드는 것은 과정도 복잡하고 시간이 많이 소모되는 작업이다. 이런 문제를 해결하는 아이디어가 바로 커넥션을 미리 생성해두고 사용하는 커넥션 풀 방법이다. 애플리케이션 시작 시점에 커넥션 풀은 필요한 만큼..
프로젝트 생성 Build.gradle dependencies { implementation 'org.springframework.boot:spring-boot-starter-jdbc' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lo..
파일 업로드 HTML 폼 전송 방식에는 application/x-www-form-urlencoded, multipart/form-data 두 가지가 있다. 파일 업로드를 이해하려면 이 두 가지 방식의 차이에 대해 이해해야 한다. HTML 폼데이터를 서버로 전송하는 가장 기본적인 방법으로, 별도의 enctype이 없으면 웹 브라우저는 요청 HTTP 메시지의 헤더에 Content-Type: application/x-www-form-urlencoded 를 추가한다. 여기서 단점은 보내야할 데이터가 여러 개인 경우, 문자와 바이너리를 동시에 전송해야하는 상황이 자주 있다는 것이다. 이 문제를 해결하기 위해 HTTP는 multipart/form-data 라는 전송 방식을 제공한다. multipart/form-da..
스프링 타입 컨버터 문자를 숫자로 변환하거나, 숫자를 문자로 변환해야하는 것처럼 애플리케이션에서 개발하다보면 타입을 변환해야 하는 경우가 상당히 많다. 이 때 스프링 타입 컨버터를 사용한다. 프로젝트 생성 다음과 같이 spring.io 에서 프로젝트를 생성하자. 스프링 타입 컨버터 소개 package hello.typeconverter.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class ..
서블릿 API 예외 처리 package hello.exception.sevlet; import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component public class WebServerCustomizer implements WebSer..
프로젝트 생성 다음과 같이 스프링 프로젝트를 생성하자. 서블릿 예외 처리 스프링 사용되기 이전에 순수 서블릿 컨테이너는 예외를 어떻게 처리하는 지 알아보자. 서블릿은 Exception, response.sendError(Http 상태 코드, 오류 메시지) 총 2가지 방식으로 예외 처리를 지원한다. Exception 자바 직접 실행 자바의 메인 메서드를 직접 실행하는 경우 main이라는 쓰레드가 실행된다. 실행 도중에 예외를 잡지 못하고 처음 실행한 main 메서드를 넘어서 예외가 던져지게 된다면, 예외 정보를 남기고 해당 쓰레드는 종료된다. 웹 애플리케이션 웹 애플리케이션은 사용자 요청별로 별도의 쓰레드가 할당되고, 서블릿 컨테이너 안에서 실행된다. 예외를 처리하지 않고 서블릿 컨테이너를 넘게되면 어떻게..