@Transactional 에 대해
@Transaction
스프링 프레임워크를 사용하면 보통 서비스 레이어(비즈니스로직) 에 @Transactional 어노테이션을 선언해 트랜잭션을 시작한다.
해당 어노테이션에 있으면, 메서드를 호출하기 직전에 스프링의 AOP 가 먼저 동작한다.
- 메서드가 시작하기 전 트랜잭션을 시작한다.
- 메서드가 정상적으로 종료되면 트랜잭션을 커밋하면서 종료한다.
트랜잭션을 커밋할 때, 플러시 하면서 DB에 저장하고 커밋한다.
만약, 예외가 발생하면 트랜잭션을 롤백하고 종료한다 ( 커밋은 발생 X )
+ 기본적으로 Unchecked Exception, Error 만을 롤백한다.
트랜잭션이란?
- 데이터베이스의 상태를 변경하는 작업 또는 한번에 수행되어야 하는 연산
- Begin , commit 을 자동으로 수행
- 예외 발생 시, rollback을 자동으로 수행
- 트랜잭션의 특징
처리방법
- 스프링에서는 선언적 어노테이션을 사용한다 -> @Transactional
( XML 을 이용해서 설정할 수 있는데 지양한다. ) - 적용된 범위 내에서 프록시 객체가 생성되어 commit or rollback 을 진행한다.
트랜잭션의 옵션 종류
Propagation 의 옵션
https://devlog-wjdrbs96.tistory.com/424
— 사용시 주의할 점
- 우선순위를 가지고 있다.
- Public 에서만 적용가능
— 트랜잭션의 격리 수준
https://velog.io/@guswns3371/데이터베이스-트랜잭션-격리수준
밑으로 갈수록 트랜잭션끼리 고립성은 높아지고 성능은 떨어진다.
일관성을 지키기 위해 ( 동시성 문제 ) 를 해결하기 위한 옵션
- READ UNCOMMITED : 다른 트랜잭션에서 커밋되지 않는 내용도 참조 가능
- READ COMMITED : 다른 트랜잭션에서 커밋된 내용만 참조 가능 ( 기본값 )
- REPETABLE READ : 트랜잭션에 진입하기 이전에 커밋된 내용만 참조 가능
- SERIALIZABLE : 트랜잭션에 진입하면 락을 걸어 다른 트랜잭션이 접근하지 못하도록 ( 성능 최하 )
생길 수 있는 현상
- Dirty Read : 수정중인 데이터 이며, 아직 Commit 되지 않은 값을 읽고, 롤백을 하면 다시 이전의 값을 읽어 일관성이 맞지 않는다.
- Non-Repeatable Read : 한 트랜잭션에서 쿼리를 두번 수행했을 때, 다른 트랜잭션이 값을 수정 또는 삭제해서 같은 쿼리의 결과가 다른 값이 발생하는 현상
- Phantom Read : insert 에서만 발생하는문제, 첫 번째에 없던 쿼리의 결과가 두 번째 쿼리에서 나타나는 현상
데이터에 여러 커넥션들이 수정요청을 한다.
커넥션1 이 접근할때는 락을 걸어버리면 다른 커넥션은 접근 불가.
커넥션1 이 락을 풀면 다른 커넥션이 접근 가능.
** 트랜잭션의 격리 수준을 어떻게 처리할지에 대한 방법 중 하나가 락 이다
락 => 동시성 제어
- 동시에 발생하는 수정 요청에 대한 데이터 일관성을 지키기 위한 메커니즘
트랜잭션 격리 수준
- 여러 트랜잭션에 대해 각 트랜잭션들을 어떻게 처리할지에 대한 전략
트랜잭션 => 원자성 보장 ( 성공 혹은 실패 )
낙관점 잠금 / 비관적 잠금
- 요청이 많은 서버에서 여러 트랜잭션이 동시에 같은 데이터에 업데이트를 발생 시킬 경우, 일부 요청이 유실되는 장애가 발생할 수 있다.
동시 읽기/업데이트 간에 데이터가 일관성 있도록 유지해야 한다.
- 낙관적 잠금 ( 애플리케이션 Lock )
- 트랜잭션을 필요로 하지않는다 -> 롤백을 수동으로 구현
- 데이터 갱신 시, 충돌이 발생하지 않을 것이라고 낙관적으로 보고 잠금을 거는 것
- DB에 락을 걸기보다 충돌 방지에 가깝다
- 동시에 동일한 데이터에 대한 여러 업데이트가 간섭하지 않도록 version 이라는 속성을 확인해서 엔티티의 변경사항을 감지한다
- version 과 같은 별도의 컬럼을 추가한다.
- @Version 을 이용 ( 사용하면 + 1 되며, version 이 변경되어 충돌을 막는다 ) - 비관적 잠금 ( 데이터 베이스 트랜잭션 Lock )
- 트랜잭션을 사용하며, 롤백이 자동으로 진행
- 처음부터 충돌이 발생할 것이라고 예상
- 데이터베이스에 접근할 때부터 락을 걸어버린다.
참고 :
우르의 Lock & JPA Lock
https://sabarada.tistory.com/175 - 낙관적, 비관적 락 비교