본문 바로가기

C-Language/Pro C, COMMIT ROLLBACK

Pro C, COMMIT/ROLLBACK

Pro C, COMMIT/ROLLBACK

Pro C 프로그램 한개는 하나의 트랜잭션으로 실행되므로 프로그램의 끝에서는 COMMIT을 실행해야만 DB에 영구적으로 반영된다.
DDL은 한 문장단위로 트랜잭션이 자동으로 COMMIT되므로 명시적으로 COMMIT명령을 실행할 필요는 없다.
DML은 COMMIT 명령을 실행해야만 영구적으로 반영되므로 프로그램이 종료하기 전에 꼭 COMMIT명령을 실행할 필요가 있다.
DDL이 실행되기 전과 후에 자동으로 트랜잭션이 COMMIT되기 때문에 그 때까지 반영되지 않고 있던 모든 문장들이 반영되므로 주의가 필요하다.

EXEC SQL COMMIT WORK;
EXEC SQL COMMIT WORK RELEASE;      /* RELEASE는 접속해제 */
EXEC SQL ROLLBACK WORK;
EXEC SQL ROLLBACK WORK RELEASE;


EXEC SQL WHENEVER SQLERROR GOTO err_proc;
위와 같은 방법으로 오류발생시 특정 처리루틴으로 분기한 경우, 그 루틴의 ROLLBACK문장에서 또 오류가 발생했다면, 재귀호출과 같은 상태가 되므로 무한루프가 발생하게 된다. 그러므로 ROLLBACK문장을 실행하기 전에는 무한루프를 방지하기 위해서 다음과 같은 문장을 먼저 실행할 필요가 있다.
EXEC SQL WHENEVER SQLERROR CONTINUE;
 
lEXEC SQL WHENEVER SQLERROR CONTINUE;
위의 문장은 SQLERROR가 발생해도 대응치 않고 그냥 다음을 실행하라는 의미이다.

오류발생시 오류메시지를 출력하고 ROLLBACK을 실행한 후에 프로그램을 종료하는 예
#include <stdio.h>
#include "sqlca.h"
 
int main(void) {
 EXEC SQL BEGIN DECLARE SECTION;
     char *connstr = "scott/ojtit@orcl";
     int empno;
     VARCHAR job[20];
     int deptno;
 EXEC SQL END DECLARE SECTION;
 
 empno = 1000;
 
 EXEC SQL CONNECT :connstr;
 
 if(sqlca.sqlcode == 0) {
  printf("오라클 연결 성공\n");
 }else{
  printf("오류 : 오라클 연결 실패\n");
 }
 
 EXEC SQL WHENEVER NOT FOUND GOTO error_routine;
 
 EXEC SQL
  DELETE FROM
   EMPLOYEES
  WHERE
   empno = :empno;

 EXEC SQL COMMIT WORK;
 
 EXEC SQL
  SELECT
        empno, job, deptno
  INTO
        :empno, :job, :deptno
  FROM
        EMPLOYEES
  WHERE
        empno = :empno;
  
 job.arr[job.len] = '\0';
   
 printf("empno=%d, job=%s, deptno=%d \n", empno, job.arr, deptno);
 
 printf("프로그램 종료\n");
 return 0;
 
error_routine:
 sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
 
 printf("오류코드=%d, 오류메시지=%s \n",
    sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
    
 EXEC SQL ROLLBACK WORK RELEASE;
 
 return 1;

  
}