트랜잭션

이 페이지의 스크립트 콘텐츠는 탐색 용도로만 사용되며 어떤 방식으로든 콘텐츠를 변경하지 않습니다.

이 장에서는 트랜잭션을 정의하고 데이터베이스가 트랜잭션을 처리하는 방법을 설명합니다.

트랜잭션 소개

트랜잭션은 하나 이상의 SQL 문을 포함하는 논리적 최소 작업 단위입니다.

트랜잭션은 SQL 문이 모두 커밋되도록 그룹화합니다. 이렇게 하면 데이터베이스에 적용되거나 모두 롤백됩니다. 즉, 데이터베이스에서 실행 취소됩니다. Oracle AI Database는 모든 트랜잭션에 트랜잭션 ID라는 고유 식별자를 지정합니다.

모든 Oracle 트랜잭션은 데이터베이스 트랜잭션의 기본 속성인 ACID 속성을 따릅니다. ACID는 다음의 머리글자어입니다.

트랜잭션 사용은 데이터베이스 관리 시스템이 파일 시스템과 다른 가장 중요한 방법 중 하나입니다.

샘플 트랜잭션: 계정 차변 및 대변

트랜잭션의 개념을 설명하기 위해 은행 데이터베이스를 고려해 보십시오.

고객이 저축 예금 계좌에서 당좌 예금 계좌로 현금을 이체하는 경우 거래는 다음과 같은 세 가지 별도 작업으로 구성되어야 합니다.

Oracle AI Database는 두 가지 상황을 고려해야 합니다. 세 개의 SQL 문이 모두 계정 잔액을 적절히 유지하는 경우 트랜잭션의 영향을 데이터베이스에 적용할 수 있습니다. 그러나 자금 부족, 부적합한 계정 번호 또는 하드웨어 오류와 같은 문제로 인해 트랜잭션의 명세서 중 하나 또는 두 개가 완료되지 못하는 경우 데이터베이스는 모든 계정의 잔액이 정확하도록 전체 트랜잭션을 롤백해야 합니다.

다음 그림은 은행 거래의 예입니다. 첫 번째 명세서에서 저축 계정 3209에서 $500를 뺍니다. 두 번째 진술은 당좌 예금 계좌(3208)에 $500를 더한다. 세번째 명령문은 이전 레코드를 분개 테이블에 삽입합니다. 마지막 명령문이 트랜잭션을 커밋합니다.

그림 1: 은행 거래

그림 cncpt025.gif에 대한 설명

트랜잭션 구조

데이터베이스 트랜잭션은 하나 이상의 명령문으로 구성됩니다.

특히 트랜잭션은 다음 중 하나로 구성됩니다.

트랜잭션은 시작과 종료를 가집니다.

참조:

트랜잭션 시작

트랜잭션은 첫번째 실행 가능한 SQL 문이 발견될 때 시작됩니다.

실행 가능한 SQL 문은 DML 및 DDL 문과 SET TRANSACTION 문을 포함하여 데이터베이스 인스턴스에 대한 호출을 생성하는 SQL 문입니다.

트랜잭션이 시작되면 Oracle AI Database는 사용 가능한 언두 데이터 세그먼트에 트랜잭션을 지정하여 새 트랜잭션에 대한 실행 취소 항목을 기록합니다. 트랜잭션 ID는 언두 세그먼트 및 트랜잭션 테이블 슬롯이 할당될 때까지 할당되지 않습니다. 이 슬롯은 첫번째 DML 문에서 발생합니다. 트랜잭션 ID는 트랜잭션에 고유하며 언두 세그먼트 번호, 슬롯 및 시퀀스 번호를 나타냅니다.

다음 예제는 UPDATE 문을 실행하여 트랜잭션을 시작하고 V$TRANSACTION에서 트랜잭션에 대한 세부 정보를 질의합니다.

SQL> UPDATE hr.employees SET salary=salary;

107 rows updated.

SQL> SELECT XID AS "txn id", XIDUSN AS "undo seg", XIDSLOT AS "slot",
  2  XIDSQN AS "seq", STATUS AS "txn status"
  3  FROM V$TRANSACTION;

txn id             undo seg       slot        seq txn status
---------------- ---------- ---------- ---------- ----------------
0600060037000000          6          6         55 ACTIVE

참조: "실행 취소 세그먼트"

트랜잭션 종료

트랜잭션은 여러 상황에서 종료될 수 있습니다.

다음 작업 중 하나가 발생하면 트랜잭션이 종료됩니다.

한 트랜잭션이 끝나면 다음 실행 가능한 SQL 문이 자동으로 다음 트랜잭션을 시작합니다. 다음 예제는 UPDATE를 실행하여 트랜잭션을 시작하고, ROLLBACK 문으로 트랜잭션을 종료한 다음, UPDATE를 실행하여 새 트랜잭션을 시작합니다(트랜잭션 ID는 다름).

SQL> UPDATE hr.employees SET salary=salary;
107 rows updated.

SQL> SELECT XID, STATUS FROM V$TRANSACTION;

XID              STATUS
---------------- ----------------
0800090033000000 ACTIVE

SQL> ROLLBACK;

Rollback complete.

SQL> SELECT XID FROM V$TRANSACTION;

no rows selected

SQL> UPDATE hr.employees SET last_name=last_name;

107 rows updated.

SQL> SELECT XID, STATUS FROM V$TRANSACTION;

XID              STATUS
---------------- ----------------
0900050033000000 ACTIVE

참조:

명령문 레벨 원자성

Oracle AI Database는 명령문 레벨 원자성을 지원합니다. 즉, SQL 문은 기본 작업 단위이며 완전히 성공하거나 완전히 실패합니다.

성공한 명령문은 커밋된 트랜잭션과 다릅니다. 다중 행 갱신에서 모든 행이 변경되는 경우와 같이 데이터베이스가 오류를 발생시키지 않고 구문 분석하여 원자 단위로 실행하는 경우 단일 SQL 문이 성공적으로 실행됩니다.

SQL 문 실행 중 오류가 발생하면 SQL 문이 실패하고 명령문의 모든 영향이 롤백됩니다. 이 작업은 명령문 레벨 롤백입니다. 이 작업의 특성은 다음과 같습니다.

명령문 레벨 롤백을 유발하는 오류의 예로 중복 기본 키를 삽입하려고 합니다. 동일한 데이터에 대한 경쟁 방식인 deadlock과 관련된 단일 SQL 문으로 인해 명령문 레벨 롤백이 발생할 수도 있습니다. 그러나 구문 오류와 같은 SQL 문 구문 분석 중에 발견된 오류는 아직 실행되지 않았으므로 명령문 레벨 롤백이 발생하지 않습니다.

참조:

SCN(시스템 변경사항 번호)

시스템 변경 번호(SCN)는 Oracle AI Database에서 사용하는 논리적 내부 시간 기록입니다.

SCN은 데이터베이스 내에서 발생하는 이벤트의 순서를 지정하며, 이는 트랜잭션의 ACID 속성을 만족시키는 데 필요합니다. Oracle AI Database는 SCN을 사용하여 모든 변경 사항이 디스크에 있는 것으로 알려지기 전에 SCN을 표시하므로 복구 시 불필요한 리두가 적용되지 않습니다. 또한 데이터베이스는 SCN을 사용하여 Recovery가 정지될 수 있도록 데이터 집합에 대한 리두가 없는 시점을 표시합니다.

SCN은 단조롭게 증가하는 시퀀스에서 발생합니다. 관찰된 SCN은 논리적 시점을 나타내고 반복되는 관찰은 같거나 큰 값을 반환하므로 Oracle AI Database는 시계와 같은 SCN을 사용할 수 있습니다. 한 이벤트의 SCN이 다른 이벤트의 SCN보다 낮으면 데이터베이스의 이전 시간에 SCN이 발생한 것입니다. 여러 이벤트가 동일한 SCN을 공유할 수 있으며 이는 데이터베이스에서 동시에 발생했음을 의미합니다.

모든 트랜잭션에는 SCN이 있습니다. 예를 들어, 트랜잭션이 행을 갱신하는 경우 데이터베이스는 이 갱신이 발생한 SCN을 기록합니다. 이 트랜잭션의 다른 수정 사항에는 동일한 SCN이 있습니다. 트랜잭션 커밋 시 데이터베이스는 이 커밋에 대한 SCN을 기록합니다.

Oracle AI Database는 시스템 글로벌 영역(SGA)에서 SCN을 증분합니다. 트랜잭션이 데이터를 수정하면 데이터베이스는 트랜잭션에 할당된 언두 데이터 세그먼트에 새 SCN을 기록합니다. 그런 다음 로그 기록자 프로세스는 트랜잭션의 커밋 레코드를 즉시 온라인 리두 로그에 기록합니다. 커밋 레코드는 트랜잭션의 고유한 SCN을 가집니다. 또한 Oracle AI Database는 인스턴스 복구 및 매체 복구 메커니즘의 일부로 SCN을 사용합니다.

참조: "인스턴스 복구 개요"

트랜잭션 제어 개요

트랜잭션 제어는 DML 문에 의한 변경 사항 관리 및 DML 문을 트랜잭션으로 그룹화하는 작업입니다.

일반적으로 응용 프로그램 설계자는 논리적 단위로 작업이 수행되고 데이터가 일관되게 유지되도록 트랜잭션 제어와 관련됩니다.

트랜잭션 제어에는 "트랜잭션 제어문"에 설명된 대로 다음 명령문을 사용하는 작업이 포함됩니다.

표 13-1의 세션에서는 트랜잭션 제어의 기본 개념을 보여 줍니다.

표 1 트랜잭션 제어

T 세션 설명
t0
COMMIT;
이 명령문은 세션의 모든 기존 트랜잭션을 종료합니다.
t1
SET TRANSACTION NAME 'sal_update';
이 명령문은 트랜잭션을 시작하고 이름을 sal_update로 지정합니다.
t2
UPDATE employees
 SET salary = 7000
  WHERE last_name = 'Banda';
이 명령문은 Banda의 급여를 7000으로 갱신합니다.
t3
SAVEPOINT after_banda_sal;
이 명령문은 이 트랜잭션의 변경 사항을 이 시점으로 롤백할 수 있도록 after_banda_sal라는 저장점을 생성합니다.
t4
UPDATE employees
 SET salary = 12000
  WHERE last_name = 'Greene';
이 명령문은 Greene의 급여를 12000으로 갱신합니다.
t5
SAVEPOINT after_greene_sal;
이 명령문은 이 트랜잭션의 변경 사항을 이 시점으로 롤백할 수 있도록 after_greene_sal라는 저장점을 생성합니다.
t6
ROLLBACK TO SAVEPOINT
 after_banda_sal;
이 명령문은 트랜잭션을 t3로 롤백하여 t4에서 Greene의 급여로 업데이트를 실행 취소합니다. sal_update 트랜잭션이 종료되지 않았습니다.
t7
UPDATE employees
 SET salary = 11000
  WHERE last_name = 'Greene';
이 명령문은 트랜잭션 sal_update에서 Greene의 급여를 11000으로 업데이트합니다.
t8
ROLLBACK;
이 명령문은 트랜잭션 sal_update의 모든 변경 사항을 롤백하고 트랜잭션을 종료합니다.
t9
SET TRANSACTION NAME 'sal_update2';
이 명령문은 세션에서 새 트랜잭션을 시작하고 이름을 sal_update2로 지정합니다.
t10
UPDATE employees
 SET salary = 7050
  WHERE last_name = 'Banda';
이 명령문은 Banda의 급여를 7050으로 갱신합니다.
t11
UPDATE employees
 SET salary = 10950
  WHERE last_name = 'Greene';
이 명령문은 Greene의 급여를 10950으로 갱신합니다.
t12
COMMIT;
이 명령문은 트랜잭션 sal_update2의 모든 변경 사항을 커밋하고 트랜잭션을 종료합니다. 커밋은 변경 사항이 온라인 리두 로그 파일에 저장되도록 보장합니다.

트랜잭션명

트랜잭션 이름은 트랜잭션이 수행 중인 작업에 대한 미리 알림 역할을 하는 선택적 사용자 지정 태그입니다. SET TRANSACTION ... NAME 문을 사용하여 트랜잭션의 이름을 지정합니다. 사용되는 경우 트랜잭션의 첫번째 명령문이어야 합니다.

표 13-1에서 첫번째 트랜잭션의 이름은 sal_update이고 두번째 트랜잭션의 이름은 sal_update2입니다.

트랜잭션 이름은 다음과 같은 이점을 제공합니다.

참조:

활성 트랜잭션

활성 트랜잭션은 시작되었지만 아직 커밋 또는 롤백되지 않은 트랜잭션입니다.

표 13-1에서 sal_update 트랜잭션의 데이터를 수정하는 첫번째 명령문은 Banda의 급여에 대한 업데이트입니다. 이 업데이트가 성공적으로 실행된 후 ROLLBACK 문이 트랜잭션을 종료할 때까지 sal_update 트랜잭션이 활성화됩니다.

트랜잭션에 의해 수행된 데이터 변경 사항은 트랜잭션이 커밋되거나 롤백될 때까지 일시적입니다. 트랜잭션이 종료되기 전의 데이터 상태는 다음 표와 같습니다.

트랜잭션 종료 전의 테이블 2 데이터 상태

상태 설명 자세히 알아보기
Oracle AI Database가 SGA에서 언두 정보를 생성했습니다. 언두 데이터는 트랜잭션의 SQL 문에 의해 변경된 이전 데이터 값을 포함합니다. "읽기 커밋된 격리 레벨의 읽기 일관성"
Oracle AI Database는 SGA의 온라인 리두 로그 버퍼에서 리두를 생성했습니다. 리두 로그 레코드는 데이터 블록에 대한 변경 사항과 언두 블록에 대한 변경 사항을 포함합니다. "리두 로그 버퍼 "
SGA의 데이터베이스 버퍼가 변경되었습니다. SGA의 데이터베이스 버퍼에 저장된 커밋된 트랜잭션에 대한 데이터 변경 사항이 반드시 DBW(데이터베이스 기록자)에 의해 데이터 파일에 즉시 기록될 필요는 없습니다. 디스크 쓰기는 커밋 전후에 발생할 수 있습니다. "데이터베이스 버퍼 캐시 "
데이터 변경의 영향을 받는 행은 잠깁니다. 다른 유저는 영향을 받은 행의 데이터를 변경할 수 없으며 커밋되지 않은 변경 사항도 볼 수 없습니다. "잠금 동작 요약"

저장점

저장점은 트랜잭션 컨텍스트 내에서 사용자가 선언한 중간 표시자입니다.

내부적으로 저장점 표시자는 SCN으로 분석됩니다. 저장점은 긴 트랜잭션을 작은 부분으로 나눕니다.

긴 트랜잭션에서 저장점을 사용하는 경우 트랜잭션의 현재 지점 이전에 수행되었지만 트랜잭션 내의 선언된 저장점 이후에 수행된 작업을 롤백할 수 있습니다. 따라서 오류가 발생하면 모든 명령문을 다시 제출할 필요가 없습니다. 표 13-1은 Greene 급여에 대한 업데이트를 이 저장점으로 롤백할 수 있도록 저장점 after_banda_sal를 만듭니다.

저장점으로 롤백

커밋되지 않은 트랜잭션에서 저장점으로 롤백한다는 것은 지정된 저장점 이후에 수행된 변경 사항을 언두하는 것을 의미하지만 트랜잭션 자체의 롤백을 의미하는 것은 아닙니다.

ROLLBACK TO SAVEPOINT after_banda_sal가 표 13-1에서 실행될 때와 같이 트랜잭션이 저장점으로 롤백될 때 다음이 발생합니다.

  1. Oracle AI Database는 저장점 이후에 실행되는 명령문만 롤백합니다.

    표 13-1에서 ROLLBACK TO SAVEPOINT는 Greene에 대한 UPDATE를 롤백하지만 Banda에 대한 UPDATE는 롤백하지 않습니다.

  2. Oracle AI Database는 ROLLBACK TO SAVEPOINT 문에 지정된 저장점을 보존하지만 이후의 모든 저장점은 손실됩니다.

    표 13-1에서 ROLLBACK TO SAVEPOINT은 after_greene_sal 저장점이 손실되도록 합니다.

  3. Oracle AI Database는 지정된 저장점 이후에 획득한 모든 테이블 및 행 잠금을 해제하지만 저장점 이전에 획득한 모든 데이터 잠금을 유지합니다.

트랜잭션은 활성 상태로 유지되며 계속될 수 있습니다.

참조:

대기열에 넣은 트랜잭션

시나리오에 따라 저장점으로 롤백한 후에도 이전에 잠긴 리소스를 대기 중인 트랜잭션이 차단될 수 있습니다.

다른 트랜잭션에 의해 차단된 트랜잭션은 차단된 트랜잭션 자체에 enqueue되므로 차단된 트랜잭션을 계속하려면 전체 차단 트랜잭션을 커밋하거나 롤백해야 합니다.

다음 표에 나오는 시나리오에서 세션 1은 DML 문을 실행하기 전에 생성된 저장점으로 롤백됩니다. 그러나 세션 2는 세션 1 트랜잭션이 완료되기를 대기하고 있기 때문에 여전히 차단됩니다.

테이블 3 저장점 예제로 롤백

T 세션 1 세션 2 세션 3 설명
t0
UPDATE employees
  SET salary=7000
  WHERE last_name=
  'Banda';
    세션 1은 트랜잭션을 시작합니다. 세션은 테이블에 Banda 행(TX) 및 하위 배타적 테이블 잠금(SX)을 배타적으로 잠급니다.
t1
SAVEPOINT
  after_banda_sal;
    세션 1은 after_banda_sal라는 저장점을 생성합니다.
t2
UPDATE employees
  SET salary=12000
  WHERE last_name=
  'Greene';
    세션 1은 Greene 행을 잠급니다.
t3  
UPDATE employees
  SET salary=14000
  WHERE last_name=
 'Greene';
  세션 2는 Greene 행을 갱신하려고 하지만 세션 1에 이 행에 대한 lock이 있기 때문에 lock을 획득하지 못합니다. 세션 2에서 시작된 트랜잭션이 없습니다.
t4
ROLLBACK
 TO SAVEPOINT
  after_banda_sal;
   

세션 1은 Greene의 급여로 갱신을 롤백하여 Greene에 대한 행 잠금을 해제합니다. t0에서 획득한 테이블 잠금은 해제되지 않습니다.

이 시점에서 세션 2는 아직 완료되지 않은 세션 1 트랜잭션을 세션 1에서 enqueue하기 때문에 세션 1에 의해 여전히 차단됩니다.

t5    
UPDATE employees
  SET salary=11000
 WHERE last_name=
 'Greene';
Greene 행은 현재 잠금 해제되어 있으므로 세션 3은 Greene 행에 대한 갱신 잠금을 획득합니다. 이 명령문은 세션 3에서 트랜잭션을 시작합니다.
t6
COMMIT;
    세션 1은 커밋되고 트랜잭션이 종료됩니다. 세션 2는 이제 세션 3에서 트랜잭션 뒤의 Greene 행으로 갱신되도록 enqueue됩니다.

참조: Oracle AI Database가 잠금을 해제하는 시기에 대해 자세히 알아보려면 "잠금 기간"을 참조하십시오.

트랜잭션 롤백

커밋되지 않은 트랜잭션의 롤백은 트랜잭션 내의 SQL 문에 의해 수행된 데이터의 변경 사항을 언두합니다.

트랜잭션이 롤백된 후에는 트랜잭션에서 수행된 작업의 영향이 더 이상 존재하지 않습니다. 저장점을 참조하지 않고 전체 트랜잭션을 롤백할 때 Oracle AI Database는 다음 작업을 수행합니다.

롤백 기간은 수정되는 데이터 양의 함수입니다.

참조:

트랜잭션 커밋

커밋은 현재 트랜잭션을 종료하고 트랜잭션에서 수행되는 모든 변경 사항을 영구적으로 적용합니다.

표 13-1에서 두번째 트랜잭션은 sal_update2로 시작하고 명시적 COMMIT 문으로 끝납니다. 이제 두 UPDATE 문에서 발생한 변경 사항은 영구적으로 적용됩니다.

트랜잭션 커밋 시 다음 작업이 수행됩니다.

트랜잭션 커밋 후 유저는 변경 사항을 확인할 수 있습니다.

일반적으로 커밋은 트랜잭션 크기에 관계없이 빠른 작업입니다. 커밋 속도는 트랜잭션에서 수정된 데이터의 크기에 따라 증가하지 않습니다. 커밋의 가장 긴 부분은 LGWR가 수행하는 물리적 디스크 I/O입니다. 하지만 LGWR가 백그라운드에서 리두 로그 버퍼의 내용을 점진적으로 기록해 두었기 때문에 소요되는 시간은 줄어듭니다.

기본 동작은 LGWR가 온라인 리두 로그에 리두를 동기적으로 기록하고 트랜잭션이 유저에게 커밋을 반환하기 전에 버퍼된 리두가 디스크에 있을 때까지 대기하는 것입니다. 그러나 트랜잭션 커밋 대기 시간이 짧을수록 응용 프로그램 개발자는 트랜잭션이 리두가 디스크에 있을 때까지 기다리지 않고 COMMIT 호출에서 즉시 반환될 수 있도록 비동기적으로 리두를 작성하도록 지정할 수 있습니다.

참조:

격리된 트랜잭션 개요

격리된 트랜잭션은 데이터베이스 복구 중 격리되고 복구되지 않는 트랜잭션입니다. 잠금을 해제하려면 먼저 DBA가 이 문제를 해결하기 위해 개입해야 합니다.

Oracle AI Database는 데이터 일관성을 위해 리두 및 언두를 활용합니다. 데이터베이스가 충돌 후 열리면 리두 적용은 데이터베이스를 롤포워드하여 모든 커밋된 변경 사항(캐시 복구라고 함)을 가져오고, 언두는 커밋되지 않은 변경 사항을 롤포워드하며, 충돌로 인해 현재 비활성화된 트랜잭션을 롤백합니다. 이를 충돌 복구라고 합니다. 데이터베이스는 커밋되지 않은 트랜잭션의 언두가 적용되어 시작 속도가 빨라질 때까지 기다리지 않습니다. 대신 트랜잭션 테이블에서 트랜잭션 상태를 "비활성"으로 표시하고 데이터베이스가 빠르게 열립니다. 비활성 트랜잭션에 대한 언두 적용은 SMON(시스템 모니터) 백그라운드 프로세스에 의해 비동기적으로 수행되며 이를 트랜잭션 복구라고 합니다.

비활성 트랜잭션이 SMON에 의해 복구되는 다른 시간은 인스턴스 복구 중에 있습니다. Oracle RAC 인스턴스는 능동적으로 실행 중인 트랜잭션과 충돌할 수 있습니다. 이러한 비활성 트랜잭션은 나머지 다른 RAC Instance의 동일한 행에 대한 트랜잭션을 차단하는 rowlock을 보유합니다. 나머지 Instance 중 하나에 대한 SMON 백그라운드 프로세스는 두 단계로 Instance Recovery를 수행하고, 그 다음에는 캐시 Recovery를 수행하고, 그 다음에는 트랜잭션 Recovery를 수행합니다.

또한 PMON 백그라운드 프로세스는 SMON으로의 프로세스 정리에 실패한 동안 대규모 트랜잭션을 종료하는 작업을 오프로드할 수 있습니다.

SMON 프로세스는 사용되지 않은 임시 세그먼트의 정리, 연속 Extent 병합 및 기타 많은 작업과 같은 시스템 레벨 작업을 수행합니다. 이 프로세스는 복구할 수 없는 프로세스로, SMON에서 고장이 발생하면 CDB Instance가 고장납니다. SMON 트랜잭션 복구 실패는 다음과 같은 다양한 원인으로 인해 발생할 수 있습니다.

충돌로 인해 SMON에 의해 현재 복구되고 있는 트랜잭션의 복구가 정지될 뿐만 아니라 나머지 비활성 트랜잭션에 대해서도 복구가 정지됩니다. 지속적 실패가 발생하면 Oracle 지원 팀은 고객이 SMON 트랜잭션 복구를 비활성화하고 데이터베이스를 열어 그 영향을 줄일 것을 권장합니다. 이로 인해 비활성 트랜잭션이 오랫동안 rowlock을 보유하게 됩니다. 이는 중요한 비즈니스 운영에 심각한 영향을 미칩니다.

Recovery할 수 없는 모든 트랜잭션은 격리되며 DBA가 문제를 해결할 수 있을 때까지 Recovery되지 않습니다. DBA는 격리된 트랜잭션에 대한 알림을 받으며 격리된 트랜잭션에 의해 보유된 행 잠금을 해제할 수 있도록 즉각적인 조치를 취해야 합니다.

DBA는 격리된 트랜잭션과 격리된 이유를 식별하는 데 도움이 되도록 다양한 로그 및 뷰에 격리된 트랜잭션이 존재함을 알립니다. DBA는 이 정보를 사용하여 격리판을 삭제할 수 있도록 특정 문제를 해결합니다.

여러 트랜잭션에서 Failure가 발생하거나 코드 버그로 인한 논리적 데이터 손상, 여러 블록의 물리적 손상 또는 PDB SGA 손상과 같은 전체 PDB에 걸쳐 발생한 경우 실패한 비활성 트랜잭션 Recovery를 격리하는 것이 도움이 될 수도 있고 그렇지 않을 수도 있습니다. 이는 다른 비활성 트랜잭션을 복구할 때 동일한 문제가 발생할 수 있으므로 이러한 실패의 근본 원인이 동일한지 여부에 따라 달라집니다. 시스템은 몇 개의 트랜잭션을 격리한 후에도 일관성 없는 상태로 계속 실행됩니다. 논리적 데이터 손상으로 인해 Failure가 발생한 경우에는 시간이 지남에 따라 분산되기 때문에 위험할 수 있습니다. 이 문제가 발생하지 않도록 하기 위해 트랜잭션 격리 한도 3개가 있으며, 그 후에 격리 수준이 데이터베이스 수준으로 에스컬레이션되고, PDB에 대해 아카이브 로깅이 사용으로 설정되어 있고 PDB를 종료할 수 있는 경우 shutdown abort를 사용하여 PDB가 종료됩니다. PDB에 대한 트랜잭션 복구는 DBA가 다음 번 시작 시 문제를 해결할 수 있도록 자동으로 비활성화됩니다. 문제가 해결되면 DBA는 다음번 시작 시 recovery를 활성화해야 합니다.

주: Oracle Data Guard는 논리적 복제를 사용하므로 격리 메타데이터는 Oracle Data Guard를 사용할 때 대기 서버로 복제되지 않습니다. 따라서 대기 서버의 트랜잭션 격리 뷰(예: DBA_QUARANTINED_TRANSACTIONS)의 콘텐츠가 기본 서버의 항목과 다를 수 있습니다.

관련 항목

Transaction Guard 개요

Transaction Guard는 애플리케이션이 트랜잭션 idempotence를 제공하는 데 사용할 수 있는 API로, 트랜잭션이 커밋 및 완료되었는지 여부를 나타내는 보장된 커밋 결과를 보존할 수 있는 데이터베이스 기능입니다. Oracle AI Database는 JDBC Thin, OCI, OCCI 및 ODP.Net용 API를 제공합니다.

복구 가능한 오류는 실행 중인 응용 프로그램 세션 논리에 관계없이 외부 시스템 오류로 인해 발생합니다. 포그라운드 프로세스, 네트워크, 노드, 저장 영역 및 데이터베이스의 계획되거나 계획되지 않은 중단 시 Recovery 가능한 오류가 발생합니다. 정전이 클라이언트 응용 프로그램과 데이터베이스 간의 연결을 끊으면 응용 프로그램이 연결 해제 오류 메시지를 수신합니다. 연결이 끊어질 때 실행 중인 트랜잭션을 진행 중인 트랜잭션이라고 합니다.

트랜잭션을 다시 제출할 것인지 또는 결과(커밋됨 또는 커밋되지 않음)를 클라이언트에 반환할 것인지 결정하려면 응용 프로그램이 실행 중인 트랜잭션의 결과를 결정해야 합니다. Oracle Database 12c 이전에는 클라이언트로 반환된 커밋 메시지가 지속되지 않았습니다. 트랜잭션을 검사해도 중복된 트랜잭션 및 다른 형태의 논리적 손상을 허용한다는 보장은 없었습니다. 예를 들어, 사용자가 온라인으로 장부를 구매할 때 웹 브라우저를 새로 고치고 동일한 장부에 대해 두 번 청구될 수 있습니다.

참조:

Transaction Guard의 이점

Oracle Database 12c부터 Transaction Guard는 Recovery 가능한 운용중단 이후의 실행 중인 트랜잭션 상태를 확인하는 툴을 응용 프로그램에 제공합니다.

응용 프로그램은 Transaction Guard를 사용하여 트랜잭션이 한 번만 실행되도록 할 수 있습니다. 예를 들어, 온라인 서점 응용 프로그램에서 이전에 제출된 커밋이 실패했음을 확인하면 응용 프로그램을 안전하게 다시 제출할 수 있습니다.

Transaction Guard는 응용 프로그램이 중복된 제출을 실행하지 않도록 하기 위해 한 번만 실행할 수 있는 도구를 제공합니다. Transaction Guard는 모든 트랜잭션에 대해 알려진 결과를 제공합니다.

Transaction Guard는 핵심 Oracle AI Database 기능입니다. 애플리케이션 연속성은 일반 사용자의 중단을 마스킹할 때 Transaction Guard를 사용합니다. Transaction Guard가 없으면 오류 후 응용 프로그램을 재시도하면 중복 트랜잭션이 커밋될 수 있습니다.

참조:

Transaction Guard 작동 방식

이 섹션에서는 커밋 메시지 손실 문제 및 Transaction Guard가 논리적 트랜잭션 ID를 사용하여 문제를 해결하는 방법에 대해 설명합니다.

손실된 커밋 메시지

idempotence용으로 설계할 때 개발자는 커밋 문을 제출한 후 통신 Failure 문제를 해결해야 합니다. 커밋 메시지는 데이터베이스에 지속되지 않으므로 Failure 후에 검색할 수 없습니다.

다음 그림은 클라이언트 응용 프로그램과 데이터베이스 간의 상호 작용을 간략하게 보여줍니다.

그림 2: 커밋 실패 메시지

그림 cncpt356.png에 대한 설명

표준 커밋 사례에서 데이터베이스는 트랜잭션을 커밋하고 클라이언트에 성공 메시지를 반환합니다. 그림 13-2에서 클라이언트는 커밋 문을 제출하고 통신이 실패했음을 알리는 메시지를 수신합니다. 이러한 유형의 Failure는 데이터베이스 Instance Failure 또는 네트워크 운용중단 등 여러 가지 이유로 발생할 수 있습니다. 이 시나리오에서는 클라이언트가 트랜잭션 상태를 알지 못합니다.

통신 장애가 발생한 후에도 데이터베이스는 여전히 제출을 실행하고 있으며 클라이언트 연결이 끊어졌는지 알지 못할 수 있습니다. 트랜잭션 상태를 확인해도 활성 트랜잭션이 확인된 후 커밋되지 않습니다. 이 오래된 정보로 인해 클라이언트가 커밋을 재전송하는 경우 데이터베이스가 트랜잭션을 반복하여 논리적 손상을 초래할 수 있습니다.

논리적 트랜잭션 ID

Oracle AI Database는 논리적 트랜잭션 ID라는 전역 고유 식별자를 사용하여 통신 실패를 해결합니다.

이 ID에는 세션이 처음 연결될 때 할당되는 논리적 세션 번호와 세션이 커밋되거나 롤링될 때마다 업데이트되는 실행 중인 커밋 번호가 포함됩니다. back.Foot 1 응용 프로그램의 관점에서 논리적 트랜잭션 ID는 실패한 세션에서 제출된 마지막 데이터베이스 트랜잭션을 고유하게 식별합니다.

하나 이상의 트랜잭션이 커밋된 클라이언트의 각 왕복에 대해 데이터베이스는 논리적 트랜잭션 ID를 저장합니다. 이 ID는 데이터를 커밋하는 각 왕복에 대해 애플리케이션과 데이터베이스 간의 상호 작용에 대한 트랜잭션 idempotence를 제공할 수 있습니다.

at-most-once 프로토콜을 사용하면 데이터베이스에서 다음을 수행하도록 하여 커밋 결과에 액세스할 수 있습니다.

트랜잭션이 실행되는 동안 데이터베이스와 클라이언트 모두 논리적 트랜잭션 ID를 보유합니다. 데이터베이스는 인증 시, 연결 풀에서 빌릴 때 및 하나 이상의 커밋 작업을 실행하는 클라이언트 드라이버에서 라운드 트립할 때마다 클라이언트에 논리적 트랜잭션 ID를 제공합니다.

응용 프로그램이 Recovery 가능한 오류 이후 마지막 트랜잭션의 결과를 확인하기 전에 응용 프로그램은 Java, OCI, OCCI 또는 ODP.Net API를 사용하여 클라이언트에 보유된 논리적 트랜잭션 ID를 얻습니다. 그런 다음 응용 프로그램은 논리적 트랜잭션 ID를 사용하여 PL/SQL 프로시저 DBMS_APP_CONT.GET_LTXID_OUTCOME을 호출하여 마지막 제출 결과(true 또는 false)와 완료된 유저 호출(true 또는 false)을 확인합니다.

Transaction Guard를 사용할 때 응용 프로그램은 오류를 recovery할 수 있고 세션의 마지막 트랜잭션이 커밋되지 않은 경우 트랜잭션을 리플레이할 수 있습니다. 마지막 트랜잭션이 커밋되고 유저 호출이 완료되면 응용 프로그램이 계속될 수 있습니다. 응용 프로그램은 Transaction Guard를 사용하여 클라이언트에 알려진 결과를 반환함으로써 클라이언트가 수행할 다음 작업을 결정할 수 있도록 합니다.

참조:

Transaction Guard: 예제

이 시나리오에서는 복구 가능한 오류로 인해 커밋 메시지가 손실됩니다.

Transaction Guard는 논리적 트랜잭션 ID를 사용하여 COMMIT 문의 결과를 보존하고, 트랜잭션에 대해 알려진 결과가 있는지 확인합니다.

그림 3: 논리적 트랜잭션 상태 확인

그림 cncpt365.png에 대한 설명

그림 13-3에서 데이터베이스는 트랜잭션이 커밋되었는지 여부와 마지막 사용자 호출이 완료되었는지 여부를 응용 프로그램에 알립니다. 그런 다음 응용 프로그램이 결과를 일반 유저에게 반환할 수 있습니다. 가능성은 다음과 같습니다.

참조: Oracle AI Database Development Guide에서 Transaction Guard 사용 방법 알아보기

애플리케이션 연속성 개요

애플리케이션 연속성은 계획되지 않은 중단 및 계획된 중단 후 불완전한 애플리케이션 요청을 재생하여 애플리케이션의 중단을 마스킹하려고 시도합니다. 이 컨텍스트에서 요청은 응용 프로그램의 작업 단위입니다.

일반적으로 요청은 단일 데이터베이스 연결에서 단일 웹 요청의 DML 문 및 기타 데이터베이스 호출에 해당합니다. 일반적으로 요청은 연결 풀에서 데이터베이스 연결의 체크 아웃과 체크 인 사이에 수행된 호출에 의해 구분됩니다.

이 단원에서는 다음 항목을 다룹니다.

애플리케이션 연속성의 이점

개발자에게 기본적인 문제는 일반 유저로부터 손실된 데이터베이스 세션을 마스킹하는 방법입니다.

Application Continuity는 모든 구성 요소가 데이터베이스와 클라이언트 간의 대화를 방해할 때 데이터베이스 세션을 복원하여 손실된 세션 문제를 해결하려고 시도합니다. 복원된 데이터베이스 세션에는 모든 상태, 커서, 변수 및 가장 최근의 트랜잭션이 포함됩니다.

애플리케이션 연속성에 대한 사용 사례

일반적으로 클라이언트는 데이터베이스에 요청을 제출하여 트랜잭션 상태와 비트랜잭션 상태를 모두 구성합니다.

클라이언트의 상태는 잠재적으로 입력된 데이터, 반환된 데이터, 캐시된 데이터 및 변수를 사용하여 현재 상태로 유지됩니다. 그러나 응용 프로그램이 작동해야 하는 데이터베이스 세션 상태는 손실됩니다.

클라이언트 요청이 하나 이상의 트랜잭션을 시작한 경우 응용 프로그램은 다음과 같은 가능성에 직면하게 됩니다.

리플레이가 성공하면 계획된 운용중단 및 계획되지 않은 운용중단에 대한 데이터베이스 유저 서비스가 중단되지 않습니다 데이터베이스가 응용 프로그램에서 보고 작업할 가능성이 있는 데이터의 변경 사항을 감지하면 리플레이가 거부됩니다 리플레이 시작에 허용된 시간이 초과되거나 응용 프로그램이 제한된 호출을 사용하거나 응용 프로그램이 disableReplay 메소드를 사용하여 명시적으로 리플레이를 비활성화한 경우에는 리플레이가 시도되지 않습니다.

참조: Oracle Real Application Clusters Administration and Deployment Guide에서 데이터베이스 세션에 대해 Application Continuity의 작동 방식에 대해 자세히 알아보기

계획된 유지관리를 위한 애플리케이션 연속성

계획된 중단에 대한 애플리케이션 연속성을 통해 애플리케이션은 안정적으로 비우거나 마이그레이션할 수 있는 데이터베이스 세션에 대한 작업을 계속할 수 있습니다.

일정이 잡힌 유지보수는 애플리케이션 작업을 중단할 필요가 없습니다. 애플리케이션 연속성을 통해 현재 위치에서 유지보수의 영향을 받지 않는 새 위치로 적극적인 작업 시간을 보낼 수 있습니다. 드레인 간격이 끝나면 유지 관리가 계획된 데이터베이스 Instance에 세션이 남아 있을 수 있습니다. 이러한 세션을 강제로 연결 해제하는 대신 Application Continuity는 이러한 세션을 나머지 사이트로 페일오버하고 진행 중인 트랜잭션을 다시 제출할 수 있습니다.

응용 프로그램 연속성을 활성화하면 데이터베이스에서 다음을 수행할 수 있습니다.

SRVCTL 유틸리티, GDSCTL(Global Data Services Control Utility) 및 Oracle Data Guard Broker의 drain_timeout 및 stop_option 서비스 속성을 사용하여 계획된 유지 관리 중 드레인 동작을 제어합니다. DBMS_SERVICE 패키지는 기본 기반구조를 제공합니다.

참조:

애플리케이션 연속성 구조

애플리케이션 연속성의 주요 구성요소는 런타임, 재연결 및 재생입니다.

단계는 다음과 같습니다.

  1. 일반 런타임

    이 단계에서 응용 프로그램 연속성은 다음 작업을 수행합니다.

    • 데이터베이스 요청 식별

    • 로컬 및 데이터베이스 호출을 리플레이할 수 있는지 여부 결정

    • 필요한 경우 리플레이를 활성화하고 큐를 관리하도록 proxy 객체를 작성합니다.

    • 데이터베이스 요청 또는 리플레이가 비활성화될 때까지 원래 호출 및 이러한 호출 검증을 보유합니다.

  2. 재접속

    이 단계는 복구 가능한 오류에 의해 트리거됩니다. 응용 프로그램 연속성은 다음 작업을 수행합니다.

    • 데이터베이스 요청에 대해 리플레이가 활성화되었는지 확인합니다.

    • 시간 초과 관리

    • 데이터베이스에 대한 새 연결을 획득한 다음 적합한 데이터베이스 대상인지 검증합니다.

    • Transaction Guard를 사용하여 마지막으로 커밋된 트랜잭션(커밋된 트랜잭션이 다시 제출되지 않음)을 확인합니다.

  3. 리플레이

    응용 프로그램 연속성은 다음 작업을 수행합니다.

    • 큐에 보유된 호출 리플레이

    • 리플레이 도중 유저가 볼 수 있는 결과 변경 사항이 나타나면 리플레이를 비활성화합니다

    • 커밋을 허용하지 않지만 오류가 발생한 마지막 회수 커밋을 허용합니다.

리플레이가 성공하면 요청이 Failure 시점부터 계속됩니다.

참조:

자율운영 트랜잭션 개요

자율운영 트랜잭션은 주 트랜잭션인 다른 트랜잭션에서 호출할 수 있는 독립 트랜잭션입니다. 호출 중인 트랜잭션을 일시 중지하고, SQL 작업을 수행하고, 독립 트랜잭션에서 해당 트랜잭션을 커밋 또는 언두한 다음 호출 중인 트랜잭션을 재개할 수 있습니다.

독립 트랜잭션은 호출 중인 트랜잭션이 커밋 또는 롤백되는지 여부에 관계없이 독립적으로 수행해야 하는 작업에 유용합니다. 예를 들어, 주식 구매 트랜잭션에서 전체 주식 구매가 진행되는지 여부에 관계없이 고객 데이터를 약정하려고 합니다. 또한 전체 트랜잭션이 롤백되더라도 오류 메시지를 디버그 테이블에 기록하려고 합니다.

자율운영 트랜잭션의 특징은 다음과 같습니다.

PL/SQL에서 독립 트랜잭션은 프래그마 AUTONOMOUS_TRANSACTION로 표시된 루틴인 자율 범위 내에서 실행됩니다. 이 컨텍스트에서 루틴에는 최상위 익명 PL/SQL 블록과 PL/SQL 서브 프로그램 및 트리거가 포함됩니다. 프래그마는 컴파일러가 컴파일 옵션을 수행하도록 지시하는 지시어입니다. AUTONOMOUS_TRANSACTION 프래그마는 이 프로시저가 실행될 때 상위 트랜잭션과 독립적인 새 독립 트랜잭션으로 실행되도록 데이터베이스에 지시합니다.

다음 그림은 MT(주 루틴)에서 자율 루틴으로 그리고 다시 제어 흐름 방법을 보여줍니다. 기본 루틴은 proc1이고 자율 루틴은 proc2입니다. 독립 루틴은 제어가 주 루틴으로 반환되기 전에 여러 트랜잭션(AT1 및 AT2)을 커밋할 수 있습니다.

그림 4: 트랜잭션 제어 흐름

그림 cncpt288.gif에 대한 설명

독립 루틴의 실행 섹션을 입력하면 주 루틴이 일시 중지됩니다. 자율운영 루틴을 종료하면 기본 루틴이 재개됩니다.

그림 13-4에서 proc1 내의 COMMIT는 자체 작업뿐만 아니라 해당 세션에서 수행된 미해결 작업을 영구적으로 만듭니다. 그러나 proc2의 COMMIT는 proc2 트랜잭션에서 수행된 작업만 영구적으로 만듭니다. 따라서 트랜잭션 AT1 및 AT2의 COMMIT 문은 MT 트랜잭션에 영향을 주지 않습니다.

참조: Oracle AI Database Development Guide 및 Oracle AI Database PL/SQL Language Reference에서 자율운영 트랜잭션 사용 방법 학습

분산 트랜잭션 개요

분산 트랜잭션은 데이터베이스 링크라는 스키마 객체를 사용하여 분산 데이터베이스의 둘 이상의 고유 노드에서 데이터를 업데이트하는 하나 이상의 명령문을 포함하는 트랜잭션입니다.

분산 데이터베이스는 분산 시스템의 데이터베이스 집합으로, 애플리케이션에 단일 데이터 소스로 표시될 수 있습니다. 데이터베이스 링크는 한 데이터베이스 인스턴스가 다른 데이터베이스 인스턴스에 로그인할 수 있는 방법을 설명합니다.

로컬 데이터베이스의 트랜잭션과 달리 분산 트랜잭션은 여러 데이터베이스의 데이터를 변경합니다. 따라서 데이터베이스가 트랜잭션의 변경 사항 커밋 또는 롤백을 원자 단위로 조정해야 하므로 분산 트랜잭션 처리가 더욱 복잡해집니다. 전체 트랜잭션을 커밋하거나 롤백해야 합니다. Oracle AI Database는 네트워크 또는 시스템 장애가 발생하더라도 네트워크에 대한 트랜잭션 제어를 조정하고 데이터 일관성을 유지해야 합니다.

2단계 커밋

2단계 커밋 방식은 분산 트랜잭션에 참여하는 모든 데이터베이스가 모든 커밋 또는 트랜잭션의 명령문을 실행 취소하도록 보장합니다. 또한 이 메커니즘은 무결성 제약 조건, 원격 프로시저 호출 및 트리거에 의해 수행되는 암시적 DML을 보호합니다.

여러 데이터베이스 간의 2단계 커밋에서는 하나의 데이터베이스가 분산 트랜잭션을 조정합니다. 시작 노드를 전역 조정자라고 합니다. 조정자는 다른 데이터베이스에 커밋할 준비가 되었는지 묻습니다. 데이터베이스가 no로 응답하면 전체 트랜잭션이 롤백됩니다. 모든 데이터베이스가 '예'로 투표하면 조정자는 각 데이터베이스에서 커밋을 영구적으로 만들라는 메시지를 브로드캐스트합니다.

2단계 커밋 메커니즘은 분산 트랜잭션을 실행하는 유저에게 투명합니다. 실제로 사용자는 트랜잭션이 분산되어 있는지조차 알 필요가 없습니다. 트랜잭션의 끝을 나타내는 COMMIT 문은 2단계 커밋 방식을 자동으로 트리거합니다. 데이터베이스 응용 프로그램의 본문 내에 분산 트랜잭션을 포함시키는 데 코딩이나 복잡한 명령문 구문이 필요하지 않습니다.

참조:

미확정 트랜잭션

In-Doubt 분산 트랜잭션은 모든 유형의 시스템 또는 네트워크 오류로 인해 2단계 커밋이 중단된 경우 발생합니다.

예를 들어, 두 데이터베이스는 커밋할 준비가 된 조정 데이터베이스에 보고하지만 조정 데이터베이스 인스턴스는 메시지를 수신한 후 즉시 실패합니다. 커밋할 준비가 된 두 데이터베이스는 결과 통지를 기다리는 동안 중단됩니다.

Recovery 프로그램(RECO) 백그라운드 프로세스는 In-Doubt 분산 트랜잭션의 결과를 자동으로 해결합니다. Failure가 복구되고 통신이 재설정되면 각 로컬 Oracle 데이터베이스의 RECO 프로세스가 모든 관련 노드에서 일관되게 In-Doubt 분산 트랜잭션을 자동으로 커밋하거나 롤백합니다.

장기적인 Failure가 발생하는 경우 Oracle AI Database를 사용하면 각 로컬 관리자가 Failure로 인해 의심스러운 분산 트랜잭션을 수동으로 커밋하거나 언두할 수 있습니다. 이 옵션을 사용하면 로컬 데이터베이스 관리자가 장기적인 Failure로 인해 무기한 보유된 잠긴 리소스를 해제할 수 있습니다.

데이터베이스를 과거 시점으로 복구해야 하는 경우 데이터베이스 복구 기능을 사용하면 다른 사이트의 데이터베이스 관리자가 데이터베이스를 이전 시점으로 되돌릴 수 있습니다. 이 작업을 수행하면 전역 데이터베이스의 일관성이 유지됩니다.

참조:


각주 범례

각주 1:

Oracle RAC(Oracle Real Application Clusters)의 경우 논리적 트랜잭션 ID에는 데이터베이스 인스턴스 번호가 접두어로 포함됩니다.