WebApplication

[Spring] 스프링 MVC 트랜잭션(Transaction) 관리

coolcode 2022. 8. 7. 23:58

트랜잭션(쪼개질 수 없는 하나의 작업 단위)  >> ACID원칙(모두 참이어야 참)이라는 특성을 가지고 있다.

원자성(Atomicity) :: 하나의 트랜잭션 안에 A와 B라는 모듈이 구성되어 있다고 했을 때 A만 성공하고 B는 실패했다면 전체의 작업이 원래 상태로 돌아가야 한다. ex) rollback
일관성 (Consistency) :: 트랜잭션이 성공했다면 데이터베이스의 모든 데이터는 일관성을 유지해야만 한다. 트랜잭션으로 처리된 데이터와 일반 데이터 사이에는 전현 차이가 없어야 한다. 
격리 (Isolation) :: 트랜잭션으로 처리되는 중간에 외부에서의 간섭은 없어야 한다. (단계가 있음)
영속성 (Durability) :: 트랜잭션이 성공적으로 처리되면 그 결과는 영속적으로 보관되어야 한다. ex) commit

 

>> 트랜잭션의 대표 예시로는 내가 스터디겸 작업했던 입출금 서비스를 예로 들 수 있다. 계좌에 대해 입금을 하고 출금을 하는 각각의 거래가 하나의 단위를 이루어 계좌 이체가 되기 때문이다. 

스프링에서는 이러한 트랜잭션 처리를 간단한 어노테이션이나 xml설정으로도 처리할 수 있다. 먼저 roo-context.xml에 트랜잭션을 관리하는 Transaction Manager를 빈으로 등록한다. 어노테이션 기반으로 트랜잭션 설정 가능하도록  <tx:annotation-diven>태그를 추가한다. 

트랜잭션 인터페이스를 작성한 후 구현클래스에 하나의 트랜잭션으로 묶을 두개의 매퍼클래스를 @Autowired @Setter로 주입해준다. ServiceImpl 클래스내 트랜잭션 처리 할 메서드 선언부에는 @Transactional 어노테이션을 추가한다. 둘중 하나의 쿼리라도 잘못되어 로직이 수행되지 않는다면 로직에 반영되지 않고 Rollback된다.

 

@Transactional 속성

- 전파속성

PROPAGATION_MADATORY :: 작업은 반드시 특정한 트랜잭션이 존재한 상태에서만 가능

PROPAGATION_NESTED :: 기존에 트랜잭션이 있는 경우 포함되어서 실행

PROPAGATION_NEVER :: 트랜잭션 상황에서 실행되면 예외 발생

PROPAGATION_NOT_SUPPORTED :: 트랜잭션이 있는 경우엔 트랜잭션이 끝날 때까지 보류된 후 실행

PROPAGATION_REQUIRED :: 트랜잭션이 있으면 그 상황에서 실행하고 없으면 새로운 트랜잭션 실행

PROPAGATION_REQUIRED_NEW :: 대상은 자신만의 고유한 트랜잭션으로 실행

PROPAGATION_SUPPORTS :: 트랜잭션을 필요로 하지 않으나 트랜잭션 상황하에 있다면 포함되어서 실행

 

- 격리레벨 

DEFAULT :: DB설정 >> 기본 격리 수준

SERIALIZABLE :: 가장 높은 격리 >> 성능 저하의 우려가 있음

READ_UNCOMMITED :: 커밋되지 않은 데이터에 대한 읽기를 허용

READ_COMMITED :: 커밋된 데이터에 대해 읽기 허용

REPEATETABLE_READ :: 동일 필드에 대해 다중 접근 시 모두 동일한 결과 보장

 

- Read-only 속성 :: true인 경우 insert, update, delete 실행 시 예외 발생 >> 기본 설정은 false

- Rollback-for 예외 :: 특정 예외 발생 시 강제로 Rollback

- No-rollback-for 예외 :: 특정 예외 발생시 Rollback 처리 되지 않음

** Transactional 어노테이션의 경우 메서드에 설정하는 것 외에도 클래스나 인터페이스에 선언 가능하다. (메서드 > 클래스 > 인터페이스)