/* @tier medium @module cm @transform common-online */ /* * cm_ol_0006.pgc - 순번 채번 서비스 (CM_OL_0006) [tier=medium] * * 요청의 채번키(SEQKEY)로 공통 순번 마스터(cm_seq)를 UPDATE 로 1 * 증가시킨 뒤 증가된 순번을 SELECT 하여 발급한다. 채번은 트랜잭션 * 경계 안에서 원자적으로 수행한다(tx_begin/commit). 순환최대치를 * 넘으면 1 로 리셋한다. * (ATMI void SVC(TPSVCINFO*) 대응) */ #include #include #include "txcore.h" #include "txcore_dbio.h" #include "acq_util.h" #include "cm_core.h" EXEC SQL INCLUDE sqlca; TX_SERVICE(CM_OL_0006, ctx) { EXEC SQL BEGIN DECLARE SECTION; char h_seqkey[16]; char h_prefix[8]; long h_seqval; long h_maxval; int h_width; EXEC SQL END DECLARE SECTION; char seqkey[16]; char issued[32]; tx_log(TX_LOG_INFO, "[CM_OL_0006] 순번 채번 서비스 진입"); memset(seqkey, 0, sizeof(seqkey)); memset(issued, 0, sizeof(issued)); if (tx_buf_get(ctx->in, "SEQKEY", seqkey, sizeof(seqkey)) != TX_OK) { tx_log(TX_LOG_ERROR, "[CM_OL_0006] 채번키(SEQKEY) 누락"); tx_return(ctx, TX_EINVAL, ctx->out); return; } if (tx_begin() != TX_OK) { tx_log(TX_LOG_ERROR, "[CM_OL_0006] 트랜잭션 시작 실패"); tx_return(ctx, TX_FAIL, ctx->out); return; } memset(h_seqkey, 0, sizeof(h_seqkey)); memset(h_prefix, 0, sizeof(h_prefix)); strncpy(h_seqkey, seqkey, sizeof(h_seqkey) - 1); h_seqval = 0; h_maxval = 0; h_width = 0; /* 순환최대치/자리수/접두어 확보 (행잠금) */ EXEC SQL SELECT cur_val, max_val, seq_width, prefix INTO :h_seqval, :h_maxval, :h_width, :h_prefix FROM cm_seq WHERE seq_key = :h_seqkey FOR UPDATE; if (sqlca.sqlcode == TX_SQL_NOTFOUND) { tx_log(TX_LOG_WARN, "[CM_OL_0006] 채번키 미등록 seqkey=%s", seqkey); tx_abort(); tx_return(ctx, TX_ENOKEY, ctx->out); return; } if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("CM_OL_0006 SELECT cm_seq"); tx_abort(); tx_return(ctx, TX_EDB, ctx->out); return; } /* 다음 순번 산출 (순환) */ h_seqval = h_seqval + 1; if (h_maxval > 0 && h_seqval > h_maxval) { h_seqval = 1; tx_log(TX_LOG_INFO, "[CM_OL_0006] 순번 순환 리셋 seqkey=%s", seqkey); } EXEC SQL UPDATE cm_seq SET cur_val = :h_seqval, upd_ts = CURRENT_TIMESTAMP WHERE seq_key = :h_seqkey; if (sqlca.sqlcode != TX_SQL_OK) { TX_DBIO_LOG_ERR("CM_OL_0006 UPDATE cm_seq"); tx_abort(); tx_return(ctx, TX_EDB, ctx->out); return; } tx_commit(); /* 접두어 + 자리수 zero-padding 으로 발급번호 조립 */ if (h_width <= 0 || h_width > 18) { h_width = 10; } snprintf(issued, sizeof(issued), "%s%0*ld", h_prefix, h_width, h_seqval); tx_buf_reset(ctx->out); tx_buf_sets(ctx->out, "SEQKEY", seqkey); tx_buf_setlong(ctx->out, "SEQVAL", h_seqval); tx_buf_sets(ctx->out, "ISSUEDNO", issued); tx_log(TX_LOG_INFO, "[CM_OL_0006] 채번완료 seqkey=%s no=%s", seqkey, issued); tx_return(ctx, TX_OK, ctx->out); }