초웹개_스프링5_DB연동(4)

네코·2022년 5월 13일
0

초웹개

목록 보기
7/10
post-thumbnail

7장은 후반 프록시는 다시 읽고 정리해봐야겠다.. 8장 초반에는 음 이렇게 바뀌는구나 하고 넘어갔는데 후반 먼저 정리하고 다시 돌아가서 정리해야겠다.

트랜잭션

이메일의 유효 여부를 판단하기 위해 검증 목적의 메일 발송 서비스
=> 이메일 인증 시점에 테이블의 데이터를 변경하는 것
=> 이메일 수정, 인증 상태 변경 2개의 쿼리 실행으로 이뤄짐

이 때 첫번째 쿼리 실행 후 두번째 쿼리 수행 중에 문제 있을 경우, 첫번째 실행 결과도 취소해야 올바르게 작동함

이럴 때 두개 이상의 쿼리를 한 작업으로 묶어 실행할 때 사용하는 것 = 트랜잭션

  • 롤백 : 쿼리 실행 결과를 취소하고 기존 db 상태로 돌아가는 것
  • 커밋 : 트랜잭션으로 묶은 쿼리가 모두 성공 후 db에 반영하는 것

JDBC는 connectiond의 setAutoCommit(false)를 통해 트랜잭션 시작하고
commit(), rollback()을 이용함.

@Transactional

스프링은 @Transactioanl 애노테이션을 트랜잭션 범위에서 실행하고 싶은 메서드에 붙이면 된다.
해당 메서드에서 수행하는 쿼리들은 하나의 트랜잭션에 묶이게 됨

해당 애노테이션이 제대로 동작하려면

  • 플랫폼 트랜잭션 매니저 빈 설정
  • @Transactional 애노테이션 활성화 설정



첫번째 두번째 사진이 AppCtx에서 설정해주는 것이고 세번째 사진이 트랜잭션으로 묶을 메서드를 지정한 것이다


트랜잭션을 확인할 main메서드

트랜잭션이 시작되고 커밋되는지를 로그를 찍어 확인해본다.

pom.xml에 logback모듈을 추가하고 resources 밑에 로그 메시지 형식과 기록위치를 담은 설정파일을 작성한다.

@Transactional 과 프록시

스프링은 @Transactional 이용해 트랜잭션을 처리하기 위해 프록시 객체를 사용한다.

Config파일에서 @EnableTransactionManagement태그를 사용하면 @Transactional 붙은 빈 객체를 찾아서 프록시 객체를 생성한다.
=> getBean()으로 반환된 객체는 프록시 객체.
이 프록시 객체에서 @Transactional붙은 메서드를 호출하면
PlatformTransactionManager를 사용해 트랜잭션을 시작. (getTransaction())
=> 트랜잭션 시작 후 실제 객체의 메서드 호출
=> 성공적으로 실행되면 트랜잭션을 커밋함.
이 때 실패하면 RuntimeException을 상속받는 예외가 발생됨 이러면 롤백함
예제 초반에 WrongIdPasswordException을 구현할 때 RuntimeException을 상속받은 이유가 트랜잭션 처리를 염두해둔 것

만약 RuntimeException 외에 다른 예외도 롤백하고싶다면 @Transactional(rollbackFor = SQLException.class)처럼 작성함.

트랜잭션 전파

@Transactional에는 value, propagation, isolation, timeout 등 속성있다
이 중에서 propagation은 트랜잭션 전파 타입을 지정한다.

전파란
a클래스 필드로 b클래스를 갖는다고 하자.
a클래스의 메서드 a1과 b클래스의 메서드 b1 모두 @Transactional가 적용된다.
이 때 a1메서드에서 b1을 호출할 경우 트랜잭션은 어떤 방식으로 실행되나??

=> @Transactional 속성에 따라 다르다

만약 @Transactional속성 = REQUIRED일 경우 현재 진행 중인 트랜잭션이 있다면 해당 트랜잭션을 사용하고 없으면 생성한다.
예제를 보면 b1이 호출될 시점에 이미 a1의 트랜잭션이 있으므로 b1은 a1의 트랜잭션을 사용한다.

JDBC템플릿은 진행 중인 트랜잭션이 존재하면 해당 트랜잭션 범위에서 쿼리를 실행한다.

0개의 댓글