전체 글 194

스프링의 트랜잭션 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

JDBC(Java Database Connectivity), 커넥션 획득 방법

JDBC JDBC(Java Database Connectivity)는 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. 클라이언트가 애플리케이션 서버를 통해 데이터를 저장하거나 조회하면, 서버는 다음 과정을 통해서 데이터베이스를 사용한다. 커넥션 연결: 주로 TCP/IP를 사용해서 커넥션을 연결한다. SQL 전달: 애플리케이션 서버는 커넥션을 통해 SQL을 DB에 전달한다. 결과 응답: DB는 전달된 SQL을 수행하고 그 결과를 응답한다. 그러나 관계형 데이터베이스의 종류는 매우 다양한데, 각각의 데이터베이스마다 커넥션을 연결하는 방법, SQL을 전달하는 방법, 그리고 결과를 응답 받는 방법이 모두 다르다. 따라서 다음 두 가지 문제가 있다. 데이터베이스를 다른 종류의 데이터베이스로 변경..

CS/Database 2024.01.15

Comparable과 Comparator

Comparable과 Comparator 자바의 Comparable과 Comparator는 모두 인터페이스이다. 즉 Comparable 혹은 Comparator을 사용하려면 인터페이스 내에 선언된 메서드를 반드시 구현(오버라이드, 재정의)해야 한다. Comparable public interface Comparable { public int compareTo(T o); } Comparator @FunctionalInterface public interface Comparator { int compare(T o1, T o2); ... } [참고] Comparator 인터페이스에는 compare() 메소드 외에 여러 메소드가 있는데 compare() 메소드만 오버라이딩하면 된다. 나머지 메소드는 defaul..

Language/Java 2024.01.15

추상 클래스와 인터페이스 비교하기

추상 클래스추상 클래스는 하나 이상의 추상 메소드를 갖는 클래스를 말하며, 추상 메소드를 갖는다는 점을 제외하면 일반 클래스와 동일하다. 따라서 추상 클래스는 멤버 변수와 일반 메소드를 가질 수 있다. 추상 클래스는 미완성이므로 그 자체로 객체를 생성(인스턴스화)할 수 없다. 추상 클래스를 상속받는 자식 클래스는 추상 메소드를 반드시 오버라이딩해야 한다. 다중 상속이 불가능하다. 참고로, 추상 메소드를 사용하면 좋은 점은 다음과 같다.부모 클래스의 메소드를 추상 메소드가 아닌 일반 메소드로 정의할 수 있다. 그리고 상속받는 자식 클래스가 해당 메소드를 재정의하면 된다. 그런데 실수로 자식 클래스에서 메소드 오버라이딩을 하지 않은 경우 오류가 발생하지 않는다. 따라서 의도치 않은 결과가 나올 수 있다. 반..

Language/Java 2024.01.14

값 타입 컬렉션

JPA의 데이터 타입 JPA의 데이터 타입을 크게 분류하면 엔티티 타입과 값 타입으로 나눌 수 있다. 엔티티 타입 @Entity로 정의하는 객체 데이터가 변해도 식별자를 통해 지속적으로 추적이 가능하다. 값 타입 종류 기본 값 타입: 기본 타입, 래퍼 클래스 , String처럼 자바가 제공하는 기본 데이터 타입 임베디드 타입: JPA에서 사용자가 정의한 값 타입 컬렉션 값 타입: 두개 이상의 값 타입을 저장할 때 사용 식별자가 없으므로 변경시 추적이 불가능하며 생명주기를 엔티티에 의존한다. 값 타입 컬렉션(컬렉션 값 타입) 값 타입을 두개 이상 저장하려면 컬렉션에 보관하고, @ElementCollection과 @CollectionTable을 사용하면 된다. @Entity public class Membe..

Backend/JPA 2024.01.13

[프로그래머스] 조이스틱

https://school.programmers.co.kr/learn/courses/30/lessons/42860 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요. programmers.co.kr 각 자리의 알파벳을 바꾸는 횟수와 자리를 이동하는 횟수를 더하면 된다. 각 자리의 알파벳을 바꾸는 횟수는 간단하다. answer += Math.min(name.charAt(i) - 'A', 26 - (name.charAt(i) - 'A')); 자리를 이동하는 횟수를 구하는게 어렵다. 자리를 이동하는 방법은 다음과 같이 3가지가 있다. 쭉 오른쪽으로 이동 먼저 오른쪽으로 가다가 왼쪽으로 이동 먼저 ..

CS/Algorism 2024.01.13

[백준] 1912. 연속합

https://www.acmicpc.net/problem/1912 1912번: 연속합 첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다. www.acmicpc.net 처음에는 좀 막혔는데 아이디어만 잘 생각하면 쉽게 풀 수 있다. dp[i]를 i를 포함한 연속 합의 최댓값이라고 했을 때, dp[i] = max(dp[i - 1], input[i])이다. 주의할 점은 dp[i]가 i까지의 최댓값이 아니라, i를 포함한 경우의 최댓값이다. 따라서 답은 dp[n]이 아니라, dp 배열에서의 최댓값이다. 입력 값으로 음수가 주어질 수 있다(ex, -1, -2, -3). 즉 dp ..

CS/Algorism 2024.01.12

[백준] 15486. 퇴사 2

https://www.acmicpc.net/problem/15486 15486번: 퇴사 2 첫째 줄에 N (1 ≤ N ≤ 1,500,000)이 주어진다. 둘째 줄부터 N개의 줄에 Ti와 Pi가 공백으로 구분되어서 주어지며, 1일부터 N일까지 순서대로 주어진다. (1 ≤ Ti ≤ 50, 1 ≤ Pi ≤ 1,000) www.acmicpc.net 지난 번에 푼 퇴사 문제와 동일한데 N의 범위만 커졌다. 따라서 퇴사 문제의 답을 제출하면 시간 초과가 나고, O(N)의 시간 복잡도로 해결해야 한다. 코드를 보면 금방 이해할 수 있다. 주요 포인트는 다음과 같다. max는 i 날짜까지의 최대 수입을 의미한다. i 날짜에 일을 시작하면 일이 끝난 다음날인 nextDay에 돈을 받는다고 가정한다. dp[nextDay]..

CS/Algorism 2024.01.12

스프링의 메시지 기능(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