database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 10276 게시물 읽기
No. 10276
오라클 프로시져 plpgsql로 변환 (트랜젝션 관련)
작성자
나그네
작성일
2021-08-23 13:48
조회수
291

안녕하세요 postgresql 입문자 입니다.


오라클 pl/sql을 plpgsql로 변환 중 트랜젝션이 상이 하여 헤메고 있습니다 고수님들의 도움을 요청 드립니다.


아래 소스는 단순 인서트후 커밋하는 프로시져이며 단계별 함수를 호출하여 로그를 기록하는 로직입니다.

프로시져 및 함수에서의 commit을 제거 후 실행 하면 수행 완료 후 자동커밋으로 수행이 되지만 별도 트랜젝션 관리가 필요 할거 같아 문의 드립니다.


1. 함수내에서의 commit 처리가 가능한지?

   => 함수내의 commit이 존재한 상태에서의 수행은 에러 { 오류:  잘못된 트랜잭션 마침. 구문:  PL/pgSQL 함수 "fn_test(double precision,character varying)" 의 50번째 COMMIT

2. 프로시져내에서의 함수 및 프로시져 호출 후 commit 수행 방법

   => 프로시져내에서만 commit 존재 상태에서의 수행은 에러 { 알림:  ORACLE ERROR : [ 2D000] :하위트랜잭션이 활성화 된 상태에서는 커밋 할 수 없음 }

3. 아래 소스 방안 외 해당 로직을 수행 할수 있는 방안

   => 아래 로직을 수행할수 있는 더 좋은 방안이 있나요??


--------------------------------------------------------------------------------------------------------------------------

--함수

--------------------------------------------------------------------------------------------------------------------------

create or replace FUNCTION FN_TEST (

    IN_ID DOUBLE PRECISION DEFAULT 0,

    IN_REMARKS VARCHAR DEFAULT NULL

) RETURNS DOUBLE PRECISION

as $$

DECLARE

    V_PATH VARCHAR(100) = 'TEST';

BEGIN

    V_ID = IN_ID;

    IF V_ID = 0 THEN

        -- 시작 LOG

        SELECT nextval('SEQUENCE') INTO V_ID;


        INSERT INTO TB_LOG (

         ...

    ELSE

        -- 종료 LOG

        UPDATE TB_LOG SET END_DATE = now(),

         ...

    END IF;

    COMMIT;

    RETURN V_ID;

end $$

language plpgsql;


--------------------------------------------------------------------------------------------------------------------------

--프로시져

--------------------------------------------------------------------------------------------------------------------------

create or replace procedure SP_TEST()

as $$

DECLARE

    V_MSG VARCHAR(2000);

    V_ID DOUBLE PRECISION = 0;

BEGIN

    -- 시작 로그

    V_ID = FN_TEST(0, '시작');


    EXECUTE 'TRUNCATE TABLE TB_TABLE';

   

    INSERT /*+ APPEND */ INTO TB_TABLE (

     ...

        COMMIT;


    -- 종료 로그

    V_ID = FN_TEST(V_ID, '성공');

EXCEPTION

    WHEN OTHERS THEN

        V_MSG := 'ORACLE ERROR : [ ' || SQLSTATE || '] :' || SQLERRM;

        RAISE NOTICE '%', V_MSG;

        ROLLBACK;


        -- 에러 로그

        V_ID = FN_TEST(V_ID, '!예외 - ' || V_MSG);

end $$

language plpgsql;


 

이 글에 대한 댓글이 총 2건 있습니다.

1. 프로시져로 만들 때 commit 구문을 쓸 수 있습니다.

2. 이 프로시져 내 커밋 사용은 인터넷 검색으로 예제를 찾아보시면 될 것 같고.

3. fn_test 함수에서 commit은 빼면 될 것 같고, sp_test 에서 오류를 기록에 남겨야한다면, 먼저 로그를 commit 하고, 프로시져를 rallback 하면 될 것 같네요. 로그 기록 작업 자체가 프로시져 안에 있으면 크게 문제 되지 않을 것 같습니다.


쓸데 없는 이야기.

왜 굳이 문제 상황의 로그를 테이블에 남기는지 저는 언제나 회의가 듭니다. 어차피 문제 상황은 서버 로그에 남습니다. 서버 로그를 잘 사용하면 될 것을 비용이 많이는 테이블에 저장하려고 하는지 ...

물론 이런 말을 하면 늘 이런 말을 듣죠.

세상은 니가 생각하는 만큼 호락호락하지 않아!

그럴 때 마다 궁시렁 거립니다. 그래도 지구는 도는데 ...

김상기(ioseph)님이 2021-08-24 03:19에 작성한 댓글입니다.

어제 오늘 열심히 검색하다 찾았네요..


1. 함수 내에서의 트랜잭션 처리는 불가

2. 프로시져내 exception 존재 시 트랜잭션 불가(함수 호출이 문제가 아니였네요..ㅠㅠ;)

즉 자율트랜잭션은 상위버전은 모르겠으나 12.8까지는 불가한거 같습니다.


답변 감사 합니다

프로시져내 로그기록은 일부 이며, 작업 중간에 commit이 필요 할거 같아서 문의 드렸고요

프로시져 내 개별 트랜잭션처리를 포기하던 exception을 포기하던 해야 하겠네요....ㅠㅠ;

 

나그네님이 2021-08-24 15:01에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
10280control-m current transaction is aborted, command ignored until end of transaction block 해결 방안은 [1]
탁공
2021-09-21
46
10278postgreSQL 테이블 트리거 관련한 질문입니다. [4]
원종태
2021-09-01
185
10277This functionality requires the server to be built with libxml support. [3]
주호민대머리
2021-08-24
278
10276오라클 프로시져 plpgsql로 변환 (트랜젝션 관련) [2]
나그네
2021-08-23
291
10275xml 형식의 데이터 인서트 시 에러 [2]
질문왕
2021-08-19
321
10273VIEW 사용 [1]
강정윤
2021-07-28
590
10272right sibling’s left-link doesn’t match : block 235 link to 487 instead of expected 102 in index “metric_data_4” [4]
탁구공2
2021-07-27
591
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2021 DSN, All rights reserved.
작업시간: 0.012초, 이곳 서비스는
	PostgreSQL v13.3으로 자료를 관리합니다