이 글은 매컴싸 발표 준비 자료로 "DB Transaction에 관한 내용 + 마지막에 Spring의 @Transactional에 관한내용 조금" 을 다루고 있습니다.
Spring의 @Transactional에 대해 자세히 알고 싶으신 분은 하단의 출처의 Spring docs를 참고하시면 좋을 것 같습니다.
데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산
회복(Recovery)
- 트랜잭션 도중에 손상된 데이터베이스를 이전 상태로 복귀하는 작업
- 트랜잭션의 연산을 수행할 때 데이터베이스를 변경하기전에 로그 데이터를 생성
- 취소(Undo) 연산으로 이미 데이터베이스에 쓰여진 것도 수정할 수 있다.
-> 데이터베이스의 상태를 변환시키는 논리적 단위 이므로 CRUD 중 C, U, D에서 사용함
계좌이체로 A은행에서 B은행으로 돈을 송금하려고 하는 경우,
송금 중 알 수 없는 오류로 인해 A은행에서 돈은 빠져나갔지만, B은행의 계좌엔 입금되지 않는 상황이 발생할 수 있다.
위와 같은 상황을 막기위해선
1. A은행 계좌의 잔액에서 이체한 금액만큼 빼는 일
2. B은행 계좌의 잔액에서 해당 금액만큼 더하는 일
이 쪼개어져선 안된다.
이러한 것을 막기위해 Transaction으로 논리적 기능을 수행하기 위한 작업의 단위를 나눠놓았다.
한 개의 트랜잭션에 대한 작업이 성공적으로 끝나고 데이터베이스가 다시 일관된 상태에 있을 때, 이 갱신 또는 변환가 완료된 것을 트랜잭션 관리자에게 알려주는 연산
하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성이 깨진 경우, 이 트랜잭션의 일부가 정상적으로 처리 되었더라도 이 트랜잭션이 행한 모든 연산을 취소하는 연산
Rollback 연산시에는 해당 트랜잭션을 재시작하거나 폐기한다.
-> 전체 연산을 취소하는 이유는 트랜잭션의 원자성 성질 때문에 (아래에서 다룸)
- A는 B에게 10000원을 준다.
- B는 A에게 물건을 준다.
이 둘 중 하나만 처리되면 안된다.
- 잔액: 0보다 커야한다.
- 성별: 남/여/기타
등의 성질은 트랜잭션 연산 후에도 동일해야함
연산후에 잔액이 "-(마이너스)"를 허용하거나 성별에 "금액"등이 들어가선 안된다.
A가 어떠한 value를 가져오려 할 때, 그 사이 B가 value 값을 변경한 경우 A는 원하는 value값이 아닌 다른 value값을 가져오게 된다.
트랜잭션 완료 후 컴퓨터가 꺼지더라도 데이터는 이미 저장되었으므로 보존된다.
만약 완료 전에 컴퓨터가 꺼졌다면 원자성 원칙에 따라 트랜잭션 수행 전으로 rollback된다.
튜터님께서 DB의 Transaction과 Spring @Transactional이 완벽히 같지 않으며, 이에 혼동이 오지 않게 설명할 것을 말씀해주셔서 가볍게만 다루려 합니다. 자세한 내용은 아래 키워드 혹은 공식 문서에서 확인하시길 바랍니다.
스프링에서 트랜잭션 처리를 지원하는 방법으로 @Transactional
을 선언하여 사용하는 어노테이션 방식이 있다. 이를 선언적 트랜잭션이라고 한다.
클래스 혹은 메서드위에 @Transactional
추가되면, 이 클래스에 트랜잭션 기능이 적용된 프록시 객체가 생성이된다.
이 프록시 객체는 PlatformTransactionManager
를 사용하여 작동여부에 따라 Commit 또는 Rollback한다.
PlatformTransactionManager interface
Spring의 트랜잭션 인프라의 중앙 인터페이스로 어플리케이션은 주로 AOP를 통해 TransactionTemplate 또는 선언적 트랜잭션과 함게 작동한다.(Commit이나 Rollback과 관련된 연산 수행해주는 친구 같음)
[트랜잭션 proxy 호출 단계]