Backend/Spring 16

스프링의 트랜잭션 전파(REQUIRED, REQUIRES_NEW)

REQUIRED 옵션 [참고] 트랜잭션 전파 옵션 스프링은 다양한 트랜잭션 전파 옵션을 제공한다. 전파 옵션에 별도의 설정을 하지 않으면 REQUIRED가 기본으로 사용된다. 참고로 실무에서는 대부분 REQUIRED 옵션을 사용한다. 그리고 아주 가끔 REQUIRES_NEW을 사용하고, 나머지는 거의 사용하지 않는다. * REQUIRED: 가장 많이 사용하는 기본 설정이다. 기존 트랜잭션이 없으면 생성하고, 있으면 참여한다. * REQUIRES_NEW: 항상 새로운 트랜잭션을 생성한다. 기존 트랜잭션이 없으면 생성하고, 있어도 새로운 트랜잭션을 생성한다. 트랜잭션이 수행중이고 아직 끝나지 않았는데 또 다른 트랜잭션이 수행되면 어떻게 될까? 이때 처음 시작된 트랜잭션을 상대적으로 밖에 있기 때문에 외부 트..

Backend/Spring 2024.01.17

스프링의 트랜잭션 AOP(@Transactional)의 특징과 주의사항

트랜잭션 AOP 특징지난 글(https://olsohee.tistory.com/82)에서는 스프링이 트랜잭션을 제공하는 방식에 대해 알아봤다. 이번에는 스프링이 제공하는 트랜잭션 중 선언적 트랜잭션 관리 방식인 @Transactional에 대해 더 자세히 알아보자.@Transactional을 사용하면 스프링의 트랜잭션 AOP가 적용된다. @Transactional 어노테이션이 특정 클래스나 메소드에 하나라도 있으면 트랜잭션 AOP는 프록시를 만들어서 스프링 컨테이너에 등록한다. 즉 실제 객체(BasicService)가 아닌 프록시 객체(BasicService$$CGLIB)가 스프링 빈에 등록된다.이때 프록시 객체는 원본 객체를 상속받고, 내부에 실제 객체(BasicService)를 참조한다. 애플리케이션..

Backend/Spring 2024.01.16

스프링의 트랜잭션

스프링 없이 트랜잭션을 적용한 예제 우선 스프링 없이 트랜잭션을 적용한 예제를 살펴보자. 애플리케이션에서 트랜잭션을 적용할 때 주의할 점은 다음과 같다. 트랜잭션은 비즈니스 로직이 있는 서비스 계층에서 시작해야 한다. 비즈니스 로직에서 예외가 발생하면 비즈니스 로직에서 실행된 모든 부분이 함께 롤백되어야 하기 때문이다. 그런데 트랜잭션을 시작하려면, 우선 커넥션이 있어야 한다. 따라서 서비스 계층에서 커넥션을 획득하고, 트랜잭션 종료(커밋/롤백) 후에 커넥션을 종료해야 한다. 트랜잭션을 사용하는 동안 실행되는 로직들은 모두 같은 커넥션을 사용해야 한다. 그래야 DB의 같은 세션을 사용하여 정상적으로 트랜잭션이 동작할 수 있다. 트랜잭션을 적용한 예제는 다음과 같다. @Slf4j @RequiredArgsC..

Backend/Spring 2024.01.16

스프링의 메시지 기능(MessageSource)

MessageSource 메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource를 사용하면 된다. MessageSource는 다음과 같이 인터페이스 형태이다. public interface MessageSource { @Nullable String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale); String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException; String getMessage(MessageSourceResolvable resolva..

Backend/Spring 2024.01.11

BindingResult(FieldError, ObjectError), MessageCodesResolver를 통한 오류 코드 생성, Bean Validation

BindingResult BindingResult는 스프링이 제공하는 검증 오류를 보관하는 객체이다. 검증 오류가 발생하면 BindingResult 객체에 담아두면 된다. @PostMapping("/add") public String addItem(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) { // 필드 예외 if (!StringUtils.hasText(item.getItemName())) { bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수입니다.")); } if (item.getPrice() == nul..

Backend/Spring 2024.01.11

HttpMessageConverter, ArgumentResolver, MappingJackson2HttpMessageConverter(JSON을 이용한 @RequestBody/@ResponseBody의 동작 원리)

@RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환해준다. 그리고 @ResponseBody는 객체 반환시 객체가 JSON 형태로 변환되어 응답이 나가도록 해준다. 이들의 동작 원리를 이해하기 위해서는 직렬화/역직렬화의 개념과 스프링 MVC에서 제공하는 HttpMessageConverter에 대해 알아야 한다. 직렬화/역직렬화 직렬화(Serialization)는 객체를 문자열 또는 바이트 스트림으로 변환하는 것을 의미한다. 반대로 역직렬화(Deserialization)는 문자열 또는 바이트 스트림을 다시 객체로 변환하는 것을 의미한다. 즉 @RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환하는 역직렬화..

Backend/Spring 2024.01.10

서블릿의 예외 처리, 스프링의 예외 처리(HandlerExceptionResolver)

서블릿의 예외 처리 서블릿의 예외 처리 흐름 먼저 스프링이 아닌 순수 서블릿 컨테이너는 어떻게 예외 처리를 하는지 알아보자. 서블릿은 다음 2가지 방식의 예외 처리를 지원한다. Exception 순수 자바 프로그램의 경우, 자바의 main 메서드를 직접 실행하면 main이라는 이름의 스레드가 실행된다. 그리고 실행 도중에 발생한 예외를 잡아서 처리하지 않으면 처음에 실행한 main 메서드까지 예외가 넘어가고, 예외 정보를 남기며 해당 스레드는 종료된다. 반면, 웹 애플리케이션은 사용자 요청별로 별도의 스레드가 할당되고 서블릿 컨테이너 안에서 실행된다. 만약 컨트롤러에서 예외가 발생했는데 이를 잡지 못하면 어떻게 될까? 예외 발생시 흐름은 다음과 같다. WAS(여기까지 예외 전파) ⬅️ 필터 ⬅️ 서블릿 ..

Backend/Spring 2024.01.04

Filter, Interceptor

Filter 필터는 서블릿이 지원하는 기능이다. 필터는 다음과 같은 특징을 갖는다. 필터의 흐름: HTTP 요청 ➡️ WAS ➡️ 필터 ➡️ 서블릿(디스패처 서블릿) ➡️ 컨트롤러 즉, 디스패처 서블릿의 앞 단에서 필터가 동작하기 때문에, 필터는 스프림 범위 밖에서 처리되는 것이다. (스프링의 시작이 디스패처 서블릿이라고 이해하면 된다.) 즉, 스프링 컨테이너가 아닌 톰캣과 같은 서블릿 컨테이너에 의해 관리된다. Filter 등록 필터를 사용하려면 Filter 인터페이스를 구현하고, 해당 객체를 필터로 등록해야 한다. 그러면 서블릿 컨테이너가 필터를 싱글톤으로 생성하고 관리한다. Filter 인터페이스 public interface Filter { default void init(FilterConfig ..

Backend/Spring 2024.01.04

Spring MVC의 구조(DispatcherServlet, HandlerMapping, HandlerAdapter)

DispatcherServlet public class DispatcherServlet extends FrameworkServlet {} DispatcherServlet은 표현 계층 전면에서 HTTP 프로토콜을 통해 들어오는 모든 요청을 가장 먼저 받아 공통 작업을 처리하고, 적합한 컨트롤러에게 요청을 위임해주는 프론트 컨트롤러이다. 즉, 클라이언트로부터 어떠한 요청이 오면 톰캣과 같은 서블릿 컨테이너가 요청을 받는다. 그리고 이 모든 요청을 프론트 컨트롤러인 디스패처 서블릿에게 보낸다. 그러면 디스패처 서블릿은 공통적인 작업을 처리한 후에 해당 요청을 처리해야 하는 컨트롤러를 찾아서 요청을 위임한다. DispatcherServlet의 상속 관계는 다음과 같다. 즉, DispatcherServlet도 결..

Backend/Spring 2024.01.03

Web Server, WAS, Servlet

Web Server 웹 서버는 클라이언트가 웹 브라우저에서 어떠한 페이지 요청을 하면 웹 서버에서 그 요청을 받아 정적 컨텐츠를 제공하는 서버이다. 여기서 정적 컨텐츠란 html 문서, css, 자바스크립트, 이미지, 영상 등 즉시 응답 가능한 컨텐츠이다. 동적인 컨텐츠 요청시에는 WAS에게 클라이언트의 요청을 전달하고, WAS가 처리한 결과를 클라이언트에게 전달한다. WAS(Web Application Server) WAS는 웹 서버의 기능을 포함하여 정적 컨텐츠를 제공할 뿐만 아니라, DB 조회나 비즈니스 로직 처리 등을 요구하는 동적 컨텐츠도 제공하는 애플리케이션 서버이다. 즉 WAS는 "Web Server + Web Container(Servlet Container)"라고 정의하기도 한다. 그래서..

Backend/Spring 2024.01.02