22.04.13 ~ 22.04.14 WIL JDBC와 Transaction

3857 단어 WILSpringSpring

트랜잭션이 왜 필요할까?

예를 들어 두명이 각각 십만원씩 가지고 있고 친구에게 돈을 송금하는 상황이 있다고 하자

데이터베이스에는 이런 식으로 쿼리가 나갈 것이다

update member set money = 100000 - 30000 where member_id = ‘me’; 
update member set money =  100000 + 30000 where member_id = ‘you’;

만약 쿼리가 나갈 때마다 자동으로 커밋되어버리면(만약 두번째 줄에서 SQLException이 발생한다면) ‘me’의 돈은 빠져나갔지만 ‘you’는 돈을 받지 못한 상태가 되어버린다.(큰일난다!)

이렇듯 한 비즈니스 로직이 동작할 때는 하나의 작업처럼 동작해야 하고, 하나의 동작을 안전하게 처리할 수 있도록 도와주는 것이 Transaction의 역할이다.

트랜잭션 ACID

  • 원자성(Atomicity) : 트랜잭션 내에서 실행한 작업들은 모두 성공하거나 모두 실패해야 한다.
  • 일관성(Consistency) : 모든 트랜잭션은 일관성있는 데이터베이스 상태를 유지해야 한다.
  • 격리성(Isolation) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.
  • 지속성(Durability) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다.

트랜잭션 전파(Transaction Propagation)

트랜잭션 전파는 비즈니스 로직의 트랜잭션 범위를 정의한다.
Spring은 전파(Propagation) 세팅에 따라 트랜잭션을 관리한다.

트랜잭션 전파 종류

  • REQUIRED : @Transactional 기본값, 트랜잭션이 있다면 사용하고 없다면 새로 만듦
  • MANDATORY : 호출 전에 반드시 진행중인 트랜잭션이 존재해야 한다. 없을경우 예외
  • REQUIRED_NEW : 항상 새로운 트랜잭션이 시작, 기존 트랜잭션은 잠시 중단되고 새로운 트랜잭션을 시작했다가 다시 기존의 트랜잭션 이어서 동작
  • SUPPORTS : 트랜잭션이 꼭 필요하지는 않음. 진행중인 트랜잭션이 있을 경우 해당 트랜잭션 사용
  • NOT_SUPPORTED : 진행중인 트랜잭션이 있어도 사용하지 않음. 기존 트랜잭션은 잠시 중단
  • NEVER :이미 진행 중인 트랜잭션이 존재하면 예외 발생
  • NESTED : 이미 진행 중인 트랜잭션이 존재하면 중첩된 트랜잭션에서 실행되어야 함

출처 : Transactional propagation isolation

트랜잭션 격리 수준(Transaction Isolation Level)

트랜잭션 격리가 성공 하는 정도를 측정 한 것

isolation level을 설정하지 않으면 사용하는 DBMS에서 설정한 Isolation 값을 따른다.

출처 : transaction-isolation-level

PlatformTransactionManager

이제 우리는 비즈니스 로직에서 Transaction이 왜 필요하고 어떻게 적용하는 지 알았다.
Transaction을 사용하려면 다음과 같이 작성하면 된다.

  1. Autocommit = false
  2. 비즈니스 로직 수행
  3. 정상적으로 실행되었으면 commit, 예외가 발생했다면 rollback
  4. Transaction이 전부 다 마무리 되었다면 Autocommit을 false로 변경 후 connection 반환

하지만 JDBC, JPA 등 트랜잭션을 적용하기 위한 코드가 다르다. 만약 우리가 JDBC를 사용하다가 JPA로 변경해야 할 경우 위와 같이 작성했던 코드 모두 변경해야하는 끔찍한 일이 생긴다.

Spring은 OCP원칙을 지키기 위해 PlatformTransactionManger라는 인터페이스로 추상화했고, 이제 우리는 이 인터페이스를 통해 트랜잭션을 구현하면 된다.

Spring Transaction Abstraction

TransactionTemplate

Repository 부분의 반복되는 코드들을 JdbcTemplate이 Template Callback Method를 통해 제거해 주었듯이

Transaction도 TransactionTemplate가 지원해준다.

TransactionTemplate 사용법

@Transactional

@Transactional은 Spring AOP 기술을 사용하여 반복되는 코드를 제거하고 비즈니스 로직만 작성할 수 있도록 도와주는 애너테이션이다.

TransactionTemplate을 통해 쉽게 트랜잭션을 구현할 수 있지만 Service계층에 비즈니스 로직과 상관없는 코드가 들어간다. @Transactional을 사용하면 비즈니스 로직으로만 코드를 작성할 수 있으므로 @Transactional을 사용하자!

추가
TransactionTemplate을 이용한 방식을 programmatic transaction management
@Transactional을 이용한 방식을 declarative transaction management
라고 한다.

좋은 웹페이지 즐겨찾기