Spring 177

트랜잭션 AOP 정리 & 스프링 부트의 자동 리소스 등록

트랜잭션 AOP가 사용된 전체 흐름을 그림으로 정리 트랜잭션 AOP 적용 전체 흐름 선언적 트랜잭션 관리 선언적 트랜잭션 관리(Declarative Transaction Management) @Transactional 애노테이션 하나만 선언해서 매우 편리하게 트랜잭션을 적용하는 것을 선언적 트랜잭션 관리라 한다. 선언적 트랜잭션 관리는 과거 XML에 설정하기도 했다. 이름 그대로 해당 로직에 트랜잭션을 적용하겠다 하고 어딘가에 선언하기만 하면 트랜잭션이 적용되는 방식. 프로그래밍 방식의 트랜잭션 관리(programmatic transaction management) 트랜잭션 매니저 또는 트랜잭션 템플릿 등을 사용해서 트랜잭션 관련 코드를 직접 작성하는 것을 프로그래밍 방식의 트랜잭션 관리라 한다. 선언적..

Spring/SpringDB 2022.06.20

트랜잭션 AOP 적용

트랜잭션 AOP를 사용하는 새로운 서비스 클래스를 만들어보자.(MemberServiceV3_3) package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; import java.sql.SQLException; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @RequiredArgsConstructor ..

Spring/SpringDB 2022.06.20

트랜잭션 AOP 이해

프록시 도입 전 프록시를 도입하기 전에 기존처럼 서비스의 로직에서 트랜잭션을 직접 시작 서비스 계층의 트랜잭션 사용 코드 예시 //트랜잭션 시작 TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try { //비즈니스 로직 bizLogic(fromId, toId, money); transactionManager.commit(status); //성공시 커밋 } catch (Exception e) { transactionManager.rollback(status); //실패시 롤백 throw new IllegalStateException(e); } 프록시 도입 후 프록시 사용 시 트랜..

Spring/SpringDB 2022.06.20

트랜잭션 문제 해결 - 트랜잭션 매니저2 & 트랜잭션 탬플릿

트랜잭션 매니저의 전체 동작 흐름을 자세히 보자. 트랜잭션 매니저 1 - 트랜잭션 시작 클라이언트의 요청으로 서비스 로직을 실행 서비스 계층에서 transactionManager.getTransaction() 을 호출해서 트랜잭션을 시작한다. 트랜잭션을 시작하려면 먼저 데이터베이스 커넥션이 필요하다. 트랜잭션 매니저는 내부에서 데이터소스를 사용해서 커넥션을 생성한다. 커넥션을 수동 커밋 모드로 변경해서 실제 데이터베이스 트랜잭션을 시작한다. 커넥션을 트랜잭션 동기화 매니저에 보관한다. 트랜잭션 동기화 매니저는 쓰레드 로컬에 커넥션을 보관한다. 따라서 멀티 쓰레드 환경에 안전하게 커넥션을 보관할 수 있다. 트랜잭션 매니저2 - 로직 실행 서비스는 비즈니스 로직을 실행하면서 리포지토리의 메서드들 호출. 이 ..

Spring/SpringDB 2022.06.20

트랜잭션 문제 해결 - 트랜잭션 매니저1

MemberRepositoryV2를 복사해서 MemberRepositoryV3를 만들자. 커넥션을 가져오는 부분을 아래와 같이 변경해준다 private void close(Connection con, Statement stmt, ResultSet rs) { JdbcUtils.closeResultSet(rs); JdbcUtils.closeStatement(stmt); // 주의! 트랜잭션 동기화를 사용하려면 DataSourceUtils를 사용해야 한다. DataSourceUtils.releaseConnection(con, dataSource); } private Connection getConnection() throws SQLException { // 주의! 트랜잭션 동기화를 사용하려면 DataSourc..

Spring/SpringDB 2022.06.20

트랜잭션 추상화 & 트랜잭션 동기화

트랜잭션 추상화 인터페이스는 아래와 같다. public interface TxManager { begin(); commit(); rollback(); } 트랜잭션은 사실 단순하다. 트랜잭션을 시작하고, 비즈니스 로직의 수행이 끝나면 커밋하거나 롤백 그리고 아래와 같이 인터페이스 기반으로 각각 기술에 맞게 구현체를 만든다. JdbcTxManager: JDBC 트랜잭션 기능을 제공하는 구현체 JpaTxManager: JPA 트랜잭션 기능을 제공하는 구현체 트랜잭션 추상화와 의존관계 서비스는 특정 트랜잭션 기술에 직접 의존하는 것이 아니라, TxManager이라는 추상화된 인터페이스에 의존. 원하는 구현체를 DI를 통해서 주입하면 된다. JDBC 트랜잭션 기능이 필요하면 JdbcTxManager이라는 서비스에..

Spring/SpringDB 2022.06.20

트랜잭션 적용

서비스를 하나 만들어보자. 계좌이체 - 내 돈을 빼서 다른곳에 넣는 로직을 작성해본다. service 패키지 안에서 MembmerServiceV1 클래스를 만들고 작성해준다. package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV1; import lombok.RequiredArgsConstructor; import java.sql.SQLException; @RequiredArgsConstructor public class MemberServiceV1 { private final MemberRepositoryV1 memberRepository; public void ac..

Spring/SpringDB 2022.06.15

DB 락 - 변경 / 조회

DB 락 - 변경 기본 데이터 입력 - SQL set autocommit true; delete from member; insert into member(member_id, money) values ('memberA',10000); 변경과 락 세션1 set autocommit false; update member set money=500 where member_id = 'memberA'; 세션1이 트랜잭션을 시작하고, memberA 의 데이터를 500원으로 업데이트 했다. 아직 커밋은 하지 않았다. memberA 로우의 락은 세션1이 가지게 된다. 세션2 SET LOCK_TIMEOUT 60000; set autocommit false; update member set money=1000 where mem..

Spring/SpringDB 2022.06.15

트랜잭션 - DB 예제 - 계좌이체

계좌이체 예제를 통해서 트랜잭션이 어떻게 사용되는지 살펴보자. 계좌이체 정상 계좌이체 문자 상황 - 커밋 계좌이체 문제 상황 - 롤백 기본 데이터 입력 set autocommit true; delete from member; insert into member(member_id, money) values ('memberA',10000); insert into member(member_id, money) values ('memberB',10000); 기본 데이터 준비 memberA 10000원 memberB 10000원 계좌이체 실행 memberA 의 돈을 memberB 에게 2000원 계좌이체하는 트랜잭션을 실행해보자. 다음과 같은 2번의 update 쿼리가 수행되어야 한다. set autocommit..

Spring/SpringDB 2022.06.15

트랜잭션 - DB 예제 - 트랜잭션 실습

h2 DB console 창 2개 띄워놓는다. 기본 데이터는 아래와 같고 데이터 초기화 SQL을 처음 h2 DB에 실행해준다. //데이터 초기화 set autocommit true; delete from member; insert into member(member_id, money) values ('oldId',10000); 데이터를 초기화하고, 세션1, 세션2에서 아래 쿼리를 실행해서 결과를 확인해보자. select * from member; 신규 데이터 추가 - 커밋 전 세션 1에서 신규 데이터를 추가해보자 - 커밋은 하지 않는다. 신규 데이터 추가 SQL //트랜잭션 시작 set autocommit false; //수동 커밋 모드 insert into member(member_id, money) v..

Spring/SpringDB 2022.06.15