자율적인 거래 Oracle PL / SQL

⚡ 스마트 요약

거래 통제 명세서 Oracle PL/SQL의 COMMIT, ROLLBACK, SAVEPOINT 문은 보류 중인 DML 변경 사항을 저장할지 또는 폐기할지 결정합니다. 자율 트랜잭션은 메인 트랜잭션과 별도로 커밋 또는 롤백하는 독립적인 서브프로그램으로 실행됩니다.

  • 💾 저지르다: 보류 중인 모든 DML 변경 사항을 영구적으로 적용하고, 트랜잭션을 종료하고, 잠금을 해제하고, 모든 저장 지점을 삭제합니다.
  • ↩️ 롤백: 보류 중인 변경 사항을 전체 거래 또는 지정된 저장 지점으로 되돌립니다.
  • 📌 세이브포인트: 트랜잭션 내의 특정 지점을 표시하여 나중에 ROLLBACK TO 명령을 사용하여 작업의 일부만 되돌릴 수 있도록 합니다.
  • 🔀 자율적 거래: PRAGMA AUTONOMOUS_TRANSACTION 지시어를 사용하면 하위 프로그램이 자체적으로 커밋하거나 롤백할 수 있습니다.
  • 🧾 사용 사례: 자율 트랜잭션은 주요 작업이 롤백되더라도 유지되어야 하는 감사 및 오류 로깅에 적합합니다.
  • 🤖 AI 지원: GitHub Copilot과 같은 AI 도우미는 COMMIT, ROLLBACK 및 PRAGMA 블록을 작성하고 누락된 커밋을 표시합니다.

자율적인 거래 Oracle COMMIT 및 ROLLBACK을 사용한 PL/SQL

PL/SQL의 TCL 문이란 무엇입니까?

TCL은 트랜잭션 제어문(Transaction Control Statements)의 약자입니다. 이 문들은 보류 중인 트랜잭션을 저장하거나 보류 중인 트랜잭션을 롤백합니다. 트랜잭션이 저장되지 않으면 변경 사항이 적용되지 않기 때문에 TCL은 매우 중요한 역할을 합니다. DML 문 해당 내용은 데이터베이스에 영구적으로 저장되지 않습니다. 아래는 다양한 TCL 문입니다. PL / SQL.

성명서 기술설명
COMMIT 보류 중인 모든 거래를 저장합니다.
롤백 보류 중인 모든 거래를 삭제합니다.
세이브포인트 트랜잭션에서 나중에 롤백할 수 있는 시점을 생성합니다.
다음으로 롤백 지정된 저장 지점까지의 모든 보류 중인 거래를 삭제합니다.

거래는 다음 시나리오에서 완료됩니다.

  • 위의 진술 중 하나라도 발행될 때 (SAVEPOINT 제외).
  • DDL 문이 실행될 때 (DDL은 자동 커밋 문입니다).
  • DCL 문이 실행될 때 (DCL은 자동 커밋 문입니다).

세이브포인트와 롤백을 사용하여

위 표는 SAVEPOINT와 ROLLBACK TO를 소개하며, 이 둘을 함께 사용하면 트랜잭션을 부분적으로 제어할 수 있습니다. SAVEPOINT는 현재 트랜잭션 내의 지정된 지점을 표시합니다. 나중에 해당 SAVEPOINT를 사용하여 ROLLBACK TO를 실행하면 그 이후에 발생한 모든 변경 사항이 취소됩니다.ping 이전에 이루어진 작업은 그대로 남아 있습니다.

이는 여러 단계를 거치는 장시간 거래에 유용합니다. SQL 여러 단계를 거치다가 마지막 단계에서 오류가 발생하는 경우, 전체 거래를 폐기하는 대신 마지막으로 성공한 저장 지점으로 되돌려 계속 진행할 수 있습니다.

구문 :

SAVEPOINT <savepoint_name>;
   -- one or more DML statements
ROLLBACK TO <savepoint_name>;

저장 지점에 대해 기억해야 할 주요 사항:

  • 세이브포인트는 현재 트랜잭션 내에서만 존재하며, 커밋 또는 전체 롤백이 발생하면 모든 세이브포인트가 삭제됩니다.
  • 세이브포인트로 되돌리면 그 이후에 생성된 모든 세이브포인트는 지워지지만, 되돌린 세이브포인트는 유지됩니다.
  • ROLLBACK TO 명령은 트랜잭션을 종료하지 않습니다. 저장 지점 이전에 변경된 내용은 COMMIT 또는 ROLLBACK 명령을 실행할 때까지 보류 상태로 유지됩니다.
  • 저장 지점 이름을 재사용하면 새 저장 지점이 마커를 나중 위치로 이동시킵니다.

ROLLBACK TO를 사용하면 트랜잭션이 열린 상태로 유지되므로, 최종적으로 남은 변경 사항을 COMMIT할지 아니면 전체 ROLLBACK을 통해 폐기할지 결정해야 합니다.

자율 거래란?

PL/SQL에서 데이터에 대한 모든 수정 작업은 트랜잭션이라고 합니다. 트랜잭션은 저장(save) 또는 폐기(discard) 명령이 적용되면 완료된 것으로 간주됩니다. 저장 또는 폐기 명령이 적용되지 않으면 트랜잭션은 완료되지 않은 것으로 간주되며, 데이터에 대한 수정 사항은 서버에 영구적으로 저장되지 않습니다.

기본적으로 PL/SQL은 세션 중 발생하는 모든 수정 사항을 단일 트랜잭션으로 처리하며, 해당 트랜잭션을 저장하거나 폐기하면 세션에 보류 중인 모든 변경 사항에 영향을 미칩니다. 자율 트랜잭션을 사용하면 개발자는 별도의 트랜잭션에서 변경 작업을 수행하고, 메인 세션 트랜잭션에 영향을 주지 않고 해당 트랜잭션을 저장하거나 폐기할 수 있습니다.

  • 자율적인 트랜잭션은 서브프로그램 수준에서 지정할 수 있습니다.
  • 어떤 것을 만들려면 서브프로그램 다른 트랜잭션에서 작업하려면 해당 블록의 선언 섹션에 PRAGMA AUTONOMOUS_TRANSACTION 키워드를 지정해야 합니다.
  • 이는 컴파일러에게 이를 별도의 트랜잭션으로 처리하도록 지시하며, 이 블록 내에서의 저장 또는 폐기 작업은 메인 트랜잭션에 반영되지 않습니다.
  • 자율 트랜잭션을 종료하고 메인 트랜잭션으로 돌아가기 전에 COMMIT 또는 ROLLBACK 명령을 실행하는 것이 필수적입니다. 왜냐하면 한 번에 하나의 트랜잭션만 활성화될 수 있기 때문입니다.
  • 따라서 자율 거래가 시작되면, 제어권이 다시 주 거래로 돌아가기 전에 해당 거래가 저장되고 완료되어야 합니다.

구문 :

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
.
BEGIN
<execution_part>
[COMMIT|ROLLBACK]
END;
/

위 구문에서 블록은 자율적인 트랜잭션으로 생성되었습니다.

예 1 : 이 예시에서는 자율 거래가 어떻게 작동하는지 이해해 보겠습니다.

아래 스크린샷은 이러한 자율 거래 예시와 그 출력 결과를 보여줍니다. Oracle.

자율 트랜잭션 예시: 메인 트랜잭션이 롤백되는 동안 중첩 블록을 커밋하는 경우 Oracle PL / SQL

DECLARE
   l_salary   NUMBER;
   PROCEDURE nested_block IS
   PRAGMA autonomous_transaction;
    BEGIN
     UPDATE emp
       SET salary = salary + 15000
       WHERE emp_no = 1002;
   COMMIT;
   END;
BEGIN
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1001;
   dbms_output.put_line('Before Salary of 1001 is'|| l_salary);
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
   dbms_output.put_line('Before Salary of 1002 is'|| l_salary);    
   UPDATE emp 
   SET salary = salary + 5000 
   WHERE emp_no = 1001;

nested_block;
ROLLBACK;

 SELECT salary INTO  l_salary FROM emp WHERE emp_no = 1001;
 dbms_output.put_line('After Salary of 1001 is'|| l_salary);
 SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
 dbms_output.put_line('After Salary of 1002 is '|| l_salary);
end;

산출

Before:Salary of 1001 is 15000 
Before:Salary of 1002 is 10000 
After:Salary of 1001 is 15000 
After:Salary of 1002 is 25000

Code 설명 :

  • Code 2행: l_salary를 NUMBER로 선언합니다.
  • Code 3행: nested_block 프로시저를 선언합니다.
  • Code 4행: nested_block 프로시저를 AUTONOMOUS_TRANSACTION으로 만듭니다.
  • Code 7-9행: 직원 번호 1002의 급여를 15000만큼 인상합니다.
  • Code 10행: 자율적 거래를 커밋합니다.
  • Code 13-16행: 변경 전 직원 1001번과 1002번의 급여 내역을 출력합니다.
  • Code 17-19행: 직원 번호 1001의 급여를 5000만큼 인상합니다.
  • Code 20행: nested_block 프로시저를 호출합니다.
  • Code 21행: 주요 거래를 폐기합니다.
  • Code 22-25행: 변경 사항을 반영한 직원 1001번과 1002번의 급여 내역을 출력합니다.

직원 번호 1001의 급여 인상은 주요 거래가 폐기되었기 때문에 반영되지 않았습니다. 직원 번호 1002의 급여 인상은 해당 항목이 별도의 거래로 생성되어 마지막에 저장되었으므로 반영되었습니다.

따라서 메인 트랜잭션에서 저장 또는 폐기 여부와 관계없이 자율 트랜잭션의 변경 사항은 메인 트랜잭션에 영향을 주지 않고 저장됩니다.

자율 트랜잭션은 언제 사용해야 할까요?

자율 트랜잭션은 강력한 기능이므로 언제 사용해야 하는지 아는 것이 중요합니다. 핵심 비즈니스 로직이 아닌, 메인 트랜잭션과 독립적으로 성공 또는 실패해야 하는 작업에 자율 트랜잭션을 사용하십시오. 일반적인 사용 사례는 다음과 같습니다.

  • 감사 로깅: 누가 언제 민감한 데이터를 변경했는지, 그리고 이전 값과 새 값을 기록하여 주 트랜잭션이 롤백되더라도 로그가 유지되도록 하십시오.
  • 오류 로깅: 오류 기록을 내부에 작성합니다. 예외 핸들러를 실행하고 커밋하면 진단 세부 정보는 유지되지만 실패한 트랜잭션은 폐기됩니다.
  • 카운터 및 통계: 호출자의 결과와 관계없이 유지되어야 하는 사용량 카운터 또는 조회 횟수를 증가시킵니다.
  • 트리거 내에서 커밋하기: 트리거는 직접 COMMIT 명령을 실행할 수 없으며, 자율 트랜잭션만이 유일하게 지원되는 방법입니다.

메인 트랜잭션과 동일한 처리 과정을 거쳐야 하는 일반적인 업데이트에는 자율 트랜잭션 사용을 지양해야 합니다. 자율 트랜잭션을 과도하게 사용하면 독립적인 커밋 뒤에 데이터가 숨겨져 디버깅이 어려워질 수 있습니다. 원칙적으로 모든 자율 블록은 명시적인 COMMIT 또는 ROLLBACK으로 끝나야 합니다.

자율 거래 vs 일반 거래

일반(주) 트랜잭션과 자율 트랜잭션의 차이점은 범위와 독립성에 있습니다. 아래 표에서 두 트랜잭션을 비교합니다.

아래 정기 거래 자율적인 거래
범위 한 세션 거래를 공유합니다. 별도의 하위 트랜잭션으로 실행됩니다.
커밋/롤백 효과 보류 중인 모든 세션 변경 사항에 영향을 미칩니다. 자율 블록에만 영향을 미칩니다.
선언 기본 동작 선언적 섹션의 PRAGMA AUTONOMOUS_TRANSACTION
부모 롤백의 효과 변경 사항이 손실됩니다 확정된 자율적 변경 사항은 유지됩니다.
일반적인 사용 핵심 비즈니스 로직 감사 및 오류 로깅

일반적인 것과는 달리 중첩 블록변경 사항이 항상 해당 블록을 둘러싼 거래의 결과를 공유하는 반면, 자율 블록은 그 자체로 독립적인 존재입니다. 이러한 차이점을 이해하면 블록이 독립적이어야 할 때와 주 거래의 결과를 공유해야 할 때를 결정하는 데 도움이 됩니다.

자주 묻는 질문

Oracle ORA-06519 오류가 발생하고 자율 작업이 롤백됩니다. 한 번에 하나의 활성 트랜잭션만 허용되므로 모든 자율 트랜잭션은 제어가 메인 트랜잭션으로 돌아가기 전에 명시적인 COMMIT 또는 ROLLBACK으로 완료되어야 합니다.

직접적으로는 불가능합니다. 일반 트리거는 COMMIT 또는 ROLLBACK 명령을 실행할 수 없습니다. 트리거 또는 트리거가 호출하는 프로시저를 PRAGMA AUTONOMOUS_TRANSACTION으로 선언하면 트리거를 실행한 명령문과 관계없이 자체적으로 변경 사항을 커밋할 수 있습니다.

아니요. 부모 트랜잭션이 일시 중단되면 자율 트랜잭션은 독립적으로 실행되며 부모 트랜잭션의 커밋되지 않은 변경 사항을 볼 수 없습니다. 데이터베이스에 이미 커밋된 데이터만 볼 수 있으므로 부모 트랜잭션의 잠금을 기다리면 교착 상태가 발생할 수 있습니다.

예. CREATE, ALTER, DROP과 같은 모든 DDL 문은 실행 전후에 암묵적인 COMMIT을 발생시킵니다. 세션에 보류 중인 모든 DML 작업은 자동으로 커밋되므로 DDL 문은 실행 후 롤백할 수 없습니다.

자율적인 블록은 다른 블록을 호출할 수 있으며, 각 블록은 자체적으로 커밋 또는 롤백을 관리합니다. Oracle TRANSACTIONS 초기화 매개변수를 통해 동시에 활성화될 수 있는 트랜잭션 수를 제한하므로, 자율 블록의 중첩이 너무 깊으면 오류가 발생할 수 있습니다.

아니요. COMMIT은 변경 사항을 영구적으로 저장하고, 잠금을 해제하며, 세이브포인트를 삭제하므로 ROLLBACK으로는 되돌릴 수 없습니다. 커밋된 데이터를 되돌리려면 새로운 DML 명령을 실행해야 합니다. 커밋하기 전에 부분적으로 되돌리려면 SAVEPOINT와 ROLLBACK TO를 사용하세요.

예. GitHub 부조종사 댓글을 기반으로 COMMIT 및 ROLLBACK 로직, SAVEPOINT 블록, PRAGMA AUTONOMOUS_TRANSACTION 프로시저를 작성합니다. Rev커밋 위치와 오류 처리를 살펴보세요. 잘못된 커밋 위치는 트랜잭션 경계를 손상시킬 수 있습니다.

AI 어시스턴트는 프로시저를 검사하여 누락되거나 잘못된 위치에 있는 COMMIT 및 ROLLBACK 문, 루프 내의 커밋, 닫히지 않은 자율 블록을 찾아냅니다. 이러한 머신러닝 기반 검토를 통해 트랜잭션 버그를 표시하고 코드가 프로덕션 환경에 배포되기 전에 더 안전한 경계를 제안합니다.

이 게시물을 요약하면 다음과 같습니다.