트랜잭션이란 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 논리적 단위
데이터베이스의 상태를 변화시킨다는 말은 SELECT, INSERT, UPDATE, DELETE 등과 같은 쿼리를 사용하는 행동을 의미
의미
1. 트랜잭션은 데이터베이스에서 병행 제어 및 회복 작업 시 처리되는 작업의 논리적 단위
2. 사용자가 시스템에 대한 서비스 요구 시 시스템이 응답하기 위한 상태 변환 과정의 작업 단위
3. 하나의 트랜잭션은 Commit 되거나 Rollback 된다.
특징
트랜잭션의 4 가지 특징 원자성( Atomicity ), 일관성( Consitency ), 독립성( Isolation ), 지속성( Durability ) => ACID
1. 원자성 (Atomicity)
- 트랜잭션의 작업이 부분적으로 실행되거나 중단되지 않는 것을 보장
- 트랜잭션이 DB에 모두 반영되거나 전혀 반영되지 않아야한다.
원자성은 수행하고 있는 트랜잭션에 의해 변경된 내역을 유지하면서, 이전에 Commit 된 상태를 임시 영역에 따로 저장함으로써 보장한다. 만약 현재 수행하고 있는 트랜잭션에서 오류가 발생하면 현재 내역을 날려버리고 임시 영역에 저장했던 상태로 Rollback 한다.
이전 데이터들이 임시로 저장되는 영역을 롤백 세그먼트 (Rollback Segment)라고 하며, 롤백 세그먼트는 수정되기 전의 파일, 블록 ID와 같은 블럭 정보 및 데이터를 저장한다. 현재 수행하고 있는 트랜잭션에 의해 새롭게 변경되는 내역을 데이터베이스 테이블이라고 한다.
여기서 오류가 발생하여 Rollback을 해야하는데 트랜잭션의 길이가 길어질 경우 오류가 발생하지 않은 곳도 다시 처음부터 작업을 수행해야하는 불상사가 발생한다. 이럴땐 특정 지점부터 Rollback 되지 않도록 Save Point를 지정하여 중간 저장 시점을 정할 수 있다.
💡 Save Point
일반적으로 Rollback을 명시하면 INSERT, DELETE, UPDATE 등의 작업 전체가 취소된다.
Save Point를 사용하면 전체가 아닌 특정 부분에서 트랜잭션을 취소시킬 수 있다.
2. 일관성 (Consitency)
- 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야한다.
- 트랜잭션 수행 전, 후 데이터 모델의 모든 제약 조건(기본 키, 외래 키, 도메인, 도메인 제약 조건 등)을 만족해야한다.
트랜잭션에서 일관성 보장은 어떤 이벤트와 조건이 발생했을 때, 트리거를 통해 보장한다.
3. 독립성, 격리성 (Isolation)
- 트랜잭션 수행 시 다른 트랜잭션의 작업이 끼어들지 못하도록 보장
- 둘 이상의 트랜잭션이 동시에 병행 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연상에 끼어들 수 없다.
트랜잭션의 격리 수준에 따라 수행 결과 참조 가능여부가 달라진다.
💡 트랜잭션 격리 수준 (Transaction Isolation Level)
트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 수준, 즉 한 트랜잭션이 다른 트랜잭션의 변경한 데이터에 대한 접근 강도를 의미
READ UNCOMMITED
트랜잭션의 변경 내용이 COMMIT 이나 ROLLBACK 과 상관없이 다른 트랜잭션에서 보여진다.
READ COMMITED
트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회 가능
REPEATABLE READ
트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회 가능하다.
SERIALIZABLE
트랜잭션이 특정 테이블을 조회하면 다른 트랜잭션은 그 테이블의 데이터를 추가/변경/삭제 불가능 (순차적 실행)
👉 내려올 수록 트랜잭션 간 고립 정도가 높아지고 성능이 떨어진다.
일반적인 온라인 서비스에서는 READ COMMITTED나 REPEATABLE READ 중 하나를 사용한다.
4. 지속성 (Durability)
- 성공적으로 수행된 트랜잭션은 영원히 반영되어야한다.
- 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행했다면 해당 데이터베이스에 영원히 반영되어야 한다.
MongoDB에서의 트랜잭션
session을 만들어서 쿼리 실행 시 생성한 session 객체를 전달
async setBootPayConfirm({ projectId, response }: { projectId: number; response: BootpayPaymentConfirmDto }) {
const session = await this.connection.startSession();
const { receipt_id, userId } = response;
await Bootpay.getAccessToken();
try {
// 트랜잭션 시작
await session.withTransaction(async () => {
const confirmData = await Bootpay.receiptPayment(receipt_id);
const { status } = confirmData;
if (status === BOOTPAY_STATUS.APPROVAL) {
// 결제 확인 검사
const data = await Bootpay.confirmPayment(receipt_id); //결제 확인 완료 처리
const { createId } = await this.bootPayRepository.setPaymentHistory({
projectId,
userId,
receipt_id,
data,
event: 'done',
});
await this.bootPayRepository.setQuestionUpdate({ projectId, createId }, session);
await this.bootPayRepository.removeAnswer(projectId, session);
await this.bootPayRepository.dropData(projectId, session);
// 결제 완료 -> 검수 대기로 변경
await this.projectService.changeLinkStatus(projectId, LINK_STATUS.REVIEW_HOLD, session);
// MARK: 결제 알림 등록
await this.agendaService.createMessageJob<IJobsPaymentAlarm>(Jobs.PAYMENT_ALARM, {
projectId,
apps: [SEND_APPS.EMAIL, SEND_APPS.NATE_ON, SEND_APPS.SMS],
LINK_STATUS: LINK_STATUS.REVIEW_HOLD,
});
}
});
return {result: true}
} catch (e) {
const info = await this.getPaymentInfo(receipt_id);
const { userId, data } = info;
const { price, tax_free } = data;
const paymentDto: PaymentCancelDto = {
name: userId,
price,
reason: '결제 실패',
receipt_id,
tax_free,
};
await this.paymentFailedAndRefund(paymentDto);
throw new BadRequestException('설문 결제가 실패되었습니다.');
} finally {
session.endSession();
}
}
https://www.mongodb.com/docs/manual/reference/method/Session/
무결성 (Integrity)
데이터의 정확성, 일관성, 유효성을 유지하는 것을 의미
개체 무결성 (Entity integrity)
모든 테이블이 기본 키(Primary key)로 선택된 필드를 가져야한다. 기본 키로 선택된 필드의 경우 고유한 값을 가져야하며, 빈 값이 허용되지 않는다.
참조 무결성 (Referential integrity)
참조 관계에 있는 두 테이블의 데이터가 항상 일관된 값을 갖도록 유지하는 것
도메인 무결성 (Domain integrity)
테이블에 존재하는 필드의 무결성을 보장하기 위한 것으로 필드의 타입, Null 값의 허용 등에 대한 사항을 정의하고 올바른 데이터가 입력 되었는지를 확인
Null 무결성 (Null integrity)
테이블의 특정 속성 값이 Null이 될 수 없게 하는 조건
고유 무결성 (Unique integrity)
테이블의 특정 속성에 대해 각 레코드들이 갖는 값들이 서로 달라야 하는 조건
키 무결성 (Key integrity)
하나의 테이블에는 적어도 하나의 키가 존재해야하는 조건
관계 무결성 (Relationship integrity)
테이블의 어느 한 레코드의 삽입 가능 여부 또는 한 테이블과 다른 테이블의 레코드들 사이의 관계에 대한 적절성 여부를 지정한 조건
Reference
https://akasai.space/db/about_isolation/
'DataBase' 카테고리의 다른 글
[MySQL] 계정 생성 및 권한 부여 (0) | 2021.04.22 |
---|---|
Oracle과 MySQL의 큰 차이점 (0) | 2021.04.22 |
[Oracle] 제약조건 (0) | 2021.04.16 |
[MySQL] 접속 (0) | 2021.04.15 |
[Oracle] 시퀀스(Sequence) (0) | 2021.04.14 |