본문 바로가기

학습 내용 정리/sql

트랜잭션

728x90

트랜잭션(Transaction)

 

작업의 완전성을 보장해주기 위해 사용되는 개념.

특정한 작업을 전부 처리하거나, 전부 실패하게 만들어 데이터의 일관성을 보장해주는 기능.

 

ACID

  • 원자성(Atomicity) 

트랜잭션 내에서 실행되는 명령들을 하나의 묶음으로 처리하여,

내부에서 실행된 명령들이 전부 성공하거나, 아니면 모두 실패해야한다는 특징

 

  • 일관성(Consistency)

트랜잭션 내부에서 처리되는 데이터의 일관성유지해야하는 특징

만약 작업이 성공할 경우 아무런 문제가 발생하지 않고,

실패하더라도 작업을 진행하던 도중 실패한 상태로 데이터를 방치하지 않는 특징

 

  • 격리성(Isolation)

트랜잭션의 경우 실행 전이나 실행 후의 데이터를 외부에서 참조할 수 있지만,

트랜잭션을 수행하는 중간 상태를 보거나 변경할 수 없도록 구성하는 특징

 

  • 지속성(Durability)

트랜잭션을 성공적으로 수행하면 수정된 데이터를 시스템에 영구적으로 적용하는 특징.

트랜잭션의 중간 결과가 아니라 완성된 결과저장하여

데이터베이스에 이상이 생기더라도 자동 복구할 수 있는 특성

 

 

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

 

여러 트랜잭션이 동시에 처리될 때

다른 트랜잭션에서 변경 및 조회하는 데이터를 읽을 수 있도록 허용하거나 거부하는 것을

결정하기 위해 사용하는 것

 

READ UNCOMMITTED

  • 커밋 되지 않은 읽기(Uncommitted Read)를 허용하는 격리 수준입니다.
  • 가장 낮은 수준의 격리수준이며, 락을 걸지 않아 동시성이 높지만 일관성이 쉽게 깨질 수 있습니다.

READ COMMITTED

  • 커밋 된 읽기(Committed Read)만을 허용하고, SELECT 문을 실행할 때 공유락을 겁니다.
  • 다른 트랜잭션이 데이터를 수정하고 있는 중에는 데이터를 읽을 수 없어 커밋되지 않은 읽기현상이 발생하지 않습니다.

REPEATABLE READ

  • 읽기를 마치더라도 공유락풀지 않으며, 트랜잭션이 완전히 종료될 때 까지 락을 유지합니다.
  • 공유락이 걸린 상태에서 데이터를 수정하는 것은 불가능하지만, 데이터를 삽입하는 것이 가능해집니다. 그로인해 팬텀 읽기가 발생할 수 있는 문제점이 있습니다.

SERIALIZABLE

  • 데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 읽거나 삽입할 수 없고, 새로운 데이터를 추가하는 것 또한 불가능합니다.
  • 가장 높은 수준의 격리 수준이므로, 동시성이 떨어지는 문제점이 존재합니다.

 


 

 

동시성(Concurrency): 여러명의 클라이언트가 하나의 데이터를 동시에 사용 공유 하는 것

 

락(Lock) :  동시성을 제어하기 위해 사용하는 기능.

해당하는 데이터를 점유하여 다른 트랜잭션의 접근을 막아 동시성일관성균형을 맞추기 위해 사용

 

- 공유 락 : 읽기 허용 쓰기 금지

- 베타 락 : 읽기 금지 쓰기 금지

 


트랜젝션 예시)

 pendingToCompleted = async (id, item_id, state, updateamount) => {
    const t = await sequelize.transaction({
      isolationLevel: Transaction.ISOLATION_LEVELS.READ_COMMITTED,
    });
    try {
      const orderUpdate = await Order_Items.update(
        { state },
        { where: { id } },
        { transaction: t },
      );

      const itemUpdate = await Items.update(
        { amount: updateamount },
        { where: { id: item_id } },
        { transaction: t },
      );
      await t.commit();
      return 1;
    } catch (err) {
      console.log(err);
      await t.rollback();
      return 0;
    }
  };
}