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

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.
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 |
| 부모 롤백의 효과 | 변경 사항이 손실됩니다 | 확정된 자율적 변경 사항은 유지됩니다. |
| 일반적인 사용 | 핵심 비즈니스 로직 | 감사 및 오류 로깅 |
일반적인 것과는 달리 중첩 블록변경 사항이 항상 해당 블록을 둘러싼 거래의 결과를 공유하는 반면, 자율 블록은 그 자체로 독립적인 존재입니다. 이러한 차이점을 이해하면 블록이 독립적이어야 할 때와 주 거래의 결과를 공유해야 할 때를 결정하는 데 도움이 됩니다.

