[Spring] 예제로 연습해본 동시성 문제 해결 과정 feat. 비관적 락 & 분산 락 & 이벤트 기반 처리
·
Spring
개요이전 포스팅에서는 분산 시스템 환경을 고려하지 않고, 단일 시스템에서의 락 관리 방법을 적용해보았다. 이번 시간에는 실제 인스턴스를 여러 개를 띄우진 않겠지만, 실제 DB도 연결한 후, 여러 인스턴스가 실행 중이라고 가정한 분산 시스템 환경에서 락을 관리하는 방법에 대해 알아보겠다!DB 및 Redis 연결간단하게 docker를 사용하여 MySQL을 실행한 후, JPA를 통해 이에 연결하도록 하겠다. 뒤에 분산 락 구현을 위해 Redis도 사용할 예정이니 미리 컨테이너로 실행해두겠다. build.gradledependencies { ... runtimeOnly 'com.mysql:mysql-connector-j' implementation 'org.springframework.boot:..
[Spring] 예제로 연습해본 동시성 문제 해결 과정 feat. ReentrantLock
·
Spring
개요과거 Java의 동시성 프로그래밍을 공부하고 포스팅까지 진행해보았고, 나름 개인 프로젝트를 진행하며 동시성 문제를 스스로 해결할 수 있는 능력이 있다고 생각했었지만, 항상 동시성 문제를 직면하게 될 때에는 머릿속에 물음표가 먼저 생겼던 것 같다. 그래서 이번 기회에 간단한 요구사항을 만족하는 시스템을 구현하여 다양한 방식으로 동시성 문제를 해결하는 연습을 해보려고 한다.거두절미하고 바로 시작하겠다. 이번에 구현할 시스템은 아주 간단한 은행 시스템이라고 가정하여 잔액 조회, 입금, 출금 로직만을 구현한다. 당연히 돈과 관련된 문제이니 동시성 문제가 발생해서는 안되니 이에 대한 처리도 해줄 것이고, 테스트 코드까지 작성해볼 예정이다.기본 기능 구현Account (도메인 모델)@Getter@NoArgsCo..
[Spring] Spring Transaction 핵심 요약
·
Spring
1. 트랜잭션 적용 확인@Transactional로 선언적 트랜잭션을 사용하면, 실제로 트랜잭션이 적용되는지 확인하기 어렵다.스프링은 AOP 프록시를 이용해 트랜잭션을 적용한다. 따라서 실제 객체가 아닌 프록시 객체가 주입된다.트랜잭션이 활성화되었는지 확인하려면 TransactionSynchronizationManager.isActualTransactionActive() 등을 사용할 수 있다.로그 설정(logging.level.org.springframework.transaction.interceptor=TRACE)을 통해 트랜잭션 시작/종료를 자세히 확인 가능하다.2. 트랜잭션 적용 위치@Transactional을 클래스와 메서드에 동시에 붙이면, 메서드 레벨이 우선순위가 더 높다(더 구체적인 곳이 우..
[Spring] 스프링의 데이터 접근 예외 추상화와 JdbcTemplate
·
Spring
JDBC 체크 예외 문제와 인터페이스서비스 계층은 특정 기술에 종속되지 않고 순수성을 유지하는 것이 좋다. 하지만 JDBC를 사용할 때 SQLException이라는 체크 예외가 발생하여 인터페이스가 특정 기술에 종속되는 문제가 생긴다. 이를 해결하려면 체크 예외를 런타임 예외로 전환하여 처리하는 방법을 사용한다.런타임 예외로 전환하는 이유체크 예외(SQLException)를 사용하면 인터페이스에도 이 예외를 명시해야 해서 특정 기술(JDBC)에 종속된다.런타임 예외를 사용하면 인터페이스에 별도 선언 없이 예외를 던질 수 있어 서비스 계층이 특정 기술에 종속되지 않게 된다.직접 만든 런타임 예외 적용법MyDbException이라는 런타임 예외를 만들어 SQLException을 감싼다.public class..
[Spring Core] Spring Core 핵심 개념
·
Spring
IoC, DI, 그리고 컨테이너IoC(제어의 역전)기존에는 클라이언트 코드가 직접 구현체를 생성하고 실행 흐름을 제어했지만, IoC는 이 흐름 제어를 외부(AppConfig 등)가 담당하게 한다.클라이언트는 인터페이스에만 의존하여, 어떤 구현체가 주입될지 모르게 됨.Framework vs. Library:프레임워크는 애플리케이션의 흐름을 제어하고 실행함.라이브러리는 개발자가 직접 흐름을 제어함.DI(의존관계 주입)정적인 클래스 의존관계: 코드 상에서 클래스 간의 관계를 확인할 수 있음(예: 클래스 다이어그램)동적인 객체 인스턴스 의존관계: 런타임 시 실제 객체 인스턴스가 외부에서 생성되어 클라이언트에 주입됨DI를 통해 클라이언트 코드를 수정하지 않고도 주입될 객체를 변경할 수 있음IoC/DI 컨테이너Ap..
[Spring Core] 스프링을 사용하는 이유?
·
Spring
객체 지향 설계와 다형성의 중요성객체 지향 프로그래밍은 추상화, 캡슐화, 상속, 다형성 등으로 구성되며, 특히 다형성은 역할(인터페이스)과 구현(구현체)을 분리하여 유연하고 확장 가능한 코드를 작성할 수 있게 한다.문제점: 단순히 다형성을 사용해도 클라이언트 코드가 구체 구현에 의존하게 되어, 구현체 변경 시 클라이언트 코드도 수정해야 하는 문제가 발생할 수 있다.= 다형성만으로는 OCP(개발-폐쇄 원칙), DIP(의존관계 역전 원칙)를 지킬 수 없다문제 해결: 스프링을 사용하지 않는 경우다형성만으로는 OCP와 DIP를 지킬 수 없다는 것을 알아보았다. 즉, 변경 시 클라이언트 코드의 변경이 필요하다는 것이다. 이러한 문제는 구현체에 대한 코드가 클라이언트 코드에 그대로 노출되어 있기 때문에 발생한다. ..