내 프로젝트인 DeliDeli의 결제 취소기능을 페어프로그래밍을 하면서, 트랜잭션 어노테이션을 달아주었는데, 트랜잭션을 정확히 알고 있지는 않는 것 같아서 추가적으로 공부한 내용을 정리해볼 것이다.

트랜잭션은 '쪼갤 수 없는 작업의 최소단위' 를 말한다.
또, '데이터베이스 상태를 변화시키기 위해 수행하는 작업단위' 라고 말할 수 있다.

데이터베이스 상태를 변화시킨다는 것은
INSERT, UPDATE, DELETE ,SELECT와 같은 것을 말한다.

트랜잭션을 사용하는 이유

데이터베이스에 여러 클라이언트가 동시에 접근하거나 응용프로그램이 갱신을 처리하는 과정에서 중단될 수 있는 경우등 데이터 부정합을 방지하기위해 사용한다.

☀ 데이터 부정합
데이터가 연결되어있는 메모리 상에서 변경이 되는 경우 관련된 데이터들이 일괄적으로 값이 일치화 시키는 과정에서 데이터의 값이 다른 경우

예를 들면, A가 B에게 10000원을 송금했는데, 예상하지 못한 상황이 생겨 B의 계좌에 10000원이 송금되지않는 경우를 방지할 수 있다.

이렇게 정상적으로 처리되지 못하는 경우 Rollback이 된다.

COMMIT 과 ROLLBACK

  • Commit : 트랜잭션이 문제없이 완료되면 commit작업을 진행해서 영구적으로 db에 반영한다.
  • Rollback : 트랜잭션 처리과정에서 오류 발생시 시작전 상태로 돌아간다.

트랜잭션의 특징

Atomicity (원자성)

  • 트랜잭션에 관련된 일은 모두 실행되던지 또는 모두 실행되지 않도록 하던지 보장하는 특징

Consistency (일관성)

  • 트랜잭션이 성공했다면, 일관적인 데이터베이스 상태를 유지해야하는 특징

Isolation (격리성)

  • 트랜잭션 수행시 다른 트랜잭셩이 끼어들지 못하도록 하는 특징

Durability (지속성)

  • 트랜잭션이 성공적으로 종료되면 데이터베이스에 작업의 결과가 영구적으로 저장되어야하는 특징

내 프로젝트에 트랜잭션을 사용한 이유

@Transactional
	public void cancelPayment(long paymentId, String userId) {
		PaymentDTO dto = getPaymentSummary(paymentId, userId);
		validateUnableToCancelPayment(dto);
		validateCorrectPaymentOwner(dto, userId);
		paymentDao.updatePaymentStatusCanceled(paymentId, userId);
	}

이 메소드는 결제 취소에 관련된 메소드이다.
메소드를 설명하자면 paymentDTO를 불러와서 취소할 수 있는 상황인지 확인하고 결제를 한 사람이 취소하려는 게 맞는지 검사한 후에 결제 취소를 해주는 역할을 가진 메소드이다.

트랜잭션을 적용하지 않으면 생길 수 있는 문제에 대해 이야기보자면,

STEP 1
A가 데이터베이스에서 paymentDTO를 불러왔을 때 결제상태는 CONFIRMED 상태였다.
STEP 2
A가 validateCorrectPaymentOwner를 실행하려고 할 때 관리자가 결제상태를 취소 불가능상태로 바꿨다.
STEP 3
A가 가지고 있는 값은 CONFIRM상태이기때문에 로직이 꼬일 수 있다.

이런 상황에서 paymentStaus 데이터 값이 꼬일 수 있다.
이런 상황을 방지해주기 위해서 Transactional 어노테이션을 달아주어서 데이터가 꼬이는 상황을 방지할 수 있다.





참고: https://hevodata.com/learn/transactional-database/
https://tecoble.techcourse.co.kr/post/2021-07-11-database-transaction/

profile
백엔드 개발자 (ง •̀ω•́)ง✧

0개의 댓글