Backend/Spring (19) 썸네일형 리스트형 스프링 스케줄러(@Scheduled) 사용 시 주의사항 1. 여러 스케줄링 작업이 있을 때 싱글 스레드로 인한 문제* 참고: https://olsohee.tistory.com/239 스프링은 스케줄링 작업을 위한 TaskScheduler라는 인터페이스를 제공하고, 구현체로는 다음 두가지가 사용된다.가상 스레드가 활성화된 경우(Java 21 이상 및 spring.threads.virtual.enabled가 true로 설정된 경우), SimpleAsyncTaskScheduler가상 스레드가 활성화되지 않은 경우, ThreadPoolTaskScheduler그리고 ThreadPoolTaskScheduler는 기본적으로 하나의 스레드를 사용하며, spring.task.scheduling을 통해 설정 값을 변경할 수 있다. If virtual threads are en.. @Async, @Scheduled의 스레드에 대해 비동기 작업을 위한 스레드스프링은 비동기 작업을 위한 TaskExecutor라는 인터페이스를 제공한다. 스프링의 TaskExecutor 인터페이스는 자바의 Executor 인터페이스와 동일하다. 그리고 스프링이 제공하는 TaskExecutor의 구현체는 다음과 같다.SyncTaskExecutorSimpleAsyncTaskExecutorConcurrentTaskExecutorThreadPoolTaskExecutorDefaultManagedTaskExecutor...@EnableAsync의 JavaDoc을 살펴보면 다음과 같이 설명되어 있다.By default, Spring will be searching for an associated thread pool definition:* either a uniqu.. 스프링의 트랜잭션 전파(REQUIRED, REQUIRES_NEW) REQUIRED 옵션 [참고] 트랜잭션 전파 옵션 스프링은 다양한 트랜잭션 전파 옵션을 제공한다. 전파 옵션에 별도의 설정을 하지 않으면 REQUIRED가 기본으로 사용된다. 참고로 실무에서는 대부분 REQUIRED 옵션을 사용한다. 그리고 아주 가끔 REQUIRES_NEW을 사용하고, 나머지는 거의 사용하지 않는다. * REQUIRED: 가장 많이 사용하는 기본 설정이다. 기존 트랜잭션이 없으면 생성하고, 있으면 참여한다. * REQUIRES_NEW: 항상 새로운 트랜잭션을 생성한다. 기존 트랜잭션이 없으면 생성하고, 있어도 새로운 트랜잭션을 생성한다. 트랜잭션이 수행중이고 아직 끝나지 않았는데 또 다른 트랜잭션이 수행되면 어떻게 될까? 이때 처음 시작된 트랜잭션을 상대적으로 밖에 있기 때문에 외부 트.. 스프링의 트랜잭션 AOP(@Transactional)의 특징과 주의사항 트랜잭션 AOP 특징지난 글(https://olsohee.tistory.com/82)에서는 스프링이 트랜잭션을 제공하는 방식에 대해 알아봤다. 이번에는 스프링이 제공하는 트랜잭션 중 선언적 트랜잭션 관리 방식인 @Transactional에 대해 더 자세히 알아보자.@Transactional을 사용하면 스프링의 트랜잭션 AOP가 적용된다. @Transactional 어노테이션이 특정 클래스나 메소드에 하나라도 있으면 트랜잭션 AOP는 프록시를 만들어서 스프링 컨테이너에 등록한다. 즉 실제 객체(BasicService)가 아닌 프록시 객체(BasicService$$CGLIB)가 스프링 빈에 등록된다.이때 프록시 객체는 원본 객체를 상속받고, 내부에 실제 객체(BasicService)를 참조한다. 애플리케이션.. 스프링의 트랜잭션 스프링 없이 트랜잭션을 적용한 예제 우선 스프링 없이 트랜잭션을 적용한 예제를 살펴보자. 애플리케이션에서 트랜잭션을 적용할 때 주의할 점은 다음과 같다. 트랜잭션은 비즈니스 로직이 있는 서비스 계층에서 시작해야 한다. 비즈니스 로직에서 예외가 발생하면 비즈니스 로직에서 실행된 모든 부분이 함께 롤백되어야 하기 때문이다. 그런데 트랜잭션을 시작하려면, 우선 커넥션이 있어야 한다. 따라서 서비스 계층에서 커넥션을 획득하고, 트랜잭션 종료(커밋/롤백) 후에 커넥션을 종료해야 한다. 트랜잭션을 사용하는 동안 실행되는 로직들은 모두 같은 커넥션을 사용해야 한다. 그래야 DB의 같은 세션을 사용하여 정상적으로 트랜잭션이 동작할 수 있다. 트랜잭션을 적용한 예제는 다음과 같다. @Slf4j @RequiredArgsC.. JDBC(Java Database Connectivity), 커넥션 획득 방법 JDBCJDBC(Java Database Connectivity)는 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. 클라이언트가 애플리케이션 서버를 통해 데이터를 저장하거나 조회하면, 서버는 다음 과정을 통해서 데이터베이스를 사용한다.커넥션 연결: 주로 TCP/IP를 사용해서 커넥션을 연결한다.SQL 전달: 애플리케이션 서버는 커넥션을 통해 SQL을 DB에 전달한다.결과 응답: DB는 전달된 SQL을 수행하고 그 결과를 응답한다.그러나 관계형 데이터베이스의 종류는 매우 다양한데, 각각의 데이터베이스마다 커넥션을 연결하는 방법, SQL을 전달하는 방법, 그리고 결과를 응답 받는 방법이 모두 다르다. 따라서 다음 두 가지 문제가 있다.데이터베이스를 다른 종류의 데이터베이스로 변경하면(ex.. 스프링의 메시지 기능(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.. 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.. 이전 1 2 3 다음