WARNING--TRANSACTION keyword given within actual transaction level

yoachan

Member
Can anyone tells me what it was? How can I get rid of it?
It happens when I check syntax on my .p.
Progress Editor didn't tells where the problem is.
I just wanted to know what cause the warning to appears? What did I do wrong. I really have no idea.

Please help.

My regards

YoChan
 

TomBascom

Curmudgeon
It means exactly what it says.

There is a transaction already active. Either because you have nested transactions using the TRANSACTION keyword or because an implicit transaction is active in the block enclosing the TRANSACTION keyword.

Compile with XREF to see where the compiler thinks the enclosing transaction is scoped.

My guess is that you have a transaction scoped to the procedure block.
 

Cringer

ProgressTalk.com Moderator
Staff member
If you can't work it out then pop your code up here and someone will be able to help you on the way. :)
 

yoachan

Member
@Cringer:
Here is my code :)

@Tom:
Yup, you were right. I have nested TRANCACTION within a TRANSACTION. Have correct my code, and everything is OK. But I'm still confused with one thing.

Here is a some of my code before:
Code:
PROCEDURE doEverything:
    DEF INPUT  PARAM lvTemp_Batch    LIKE trn_prd.trp_batch.
    DEF OUTPUT PARAM lvOtherFeedback AS LOGICAL.
    DEF BUFFER bfr_trst FOR trst_tmp.

    FOR EACH trst_tmp WHERE trst_tmp.trst_flag   EQ cFlagRestore# AND 
                            trst_tmp.trst_user   EQ myUser        AND 
                            trst_tmp.trst_chr01  EQ lvTemp_Batch  AND 
                            trst_tmp.trst_status EQ NO
                      USE-INDEX trst_idx13
                      NO-LOCK.
        RUN doReset. /* Just resetting some global variables */

        DO TRANSACTION :
            SET vRollBack = YES.
            RUN doTransaksiScan.
        END. 

        IF vRollBack NE NO THEN DO :
            IF StatusCode EQ "" THEN 
                SET StatusCode = "Error Scanning with Batch: '" + trst_tmp.trst_chr01 + 
                                 "'; Serial Numb: '" + trst_tmp.trst_chr03 + "'".
            PUT STREAM myStream UNFORMATTED "ERROR | " StatusCode SKIP.
        END.
        ELSE DO :
            SET StatusCode = "Error Scanning with Batch: '" + trst_tmp.trst_chr01 + 
                                     "'; Serial Numb: '" + trst_tmp.trst_chr03 + "'".
            PUT STREAM myStream UNFORMATTED "OK    | " StatusCode SKIP.

            FIND FIRST bfr_trst WHERE ROWID (bfr_trst) EQ ROWID (trst_tmp)
                                EXCLUSIVE-LOCK NO-ERROR.
            IF AVAIL bfr_trst THEN DO :
                SET bfr_trst.trst_status = YES.
            END.
            ELSE DO :
                PUT STREAM myStream UNFORMATTED "ERROR | Missing Buffer on trst_tmp" SKIP.
            END. 
        END.
    END. 
    SET lvOtherFeedback = YES.
END. /* END OF PROCEDURE */
And this is after (no warning message)
Code:
...
...
        DO TRANSACTION :
            SET vRollBack = YES.
            RUN doTransaksiScan.

            IF vRollBack NE NO THEN DO :
                IF StatusCode EQ "" THEN 
                    SET StatusCode = "Error Scanning with Batch: '" + trst_tmp.trst_chr01 + 
                                     "'; Serial Numb: '" + trst_tmp.trst_chr03 + "'".
                PUT STREAM myStream UNFORMATTED "ERROR | " StatusCode SKIP.
            END.
            ELSE DO :
                SET StatusCode = "Error Scanning with Batch: '" + trst_tmp.trst_chr01 + 
                                         "'; Serial Numb: '" + trst_tmp.trst_chr03 + "'".
                PUT STREAM myStream UNFORMATTED "OK    | " StatusCode SKIP.

                FIND FIRST bfr_trst WHERE ROWID (bfr_trst) EQ ROWID (trst_tmp)
                                    EXCLUSIVE-LOCK NO-ERROR.
                IF AVAIL bfr_trst THEN DO :
                    SET bfr_trst.trst_status = YES.
                END.
                ELSE DO :
                    PUT STREAM myStream UNFORMATTED "ERROR | Missing Buffer on trst_tmp" SKIP.
                END. 
            END.
        END. 
...
...
I moved the FIND FIRST inside the TRANSACTION.
My Quastion is can't I put another EXCLUSIVE-LOCK outside the TRANSACTION?
 

yoachan

Member
My second question is:
As you notice on my code above, I have a procedure called doReset.
Here's a part of it's code before I recode it:
Code:
PROCEDURE doReset:
    SET vBatch_Par   = "".
    SET vBatch       = "".
    SET vTracebility = ?.

    SET vSettingWIP#  = ?. 
    SET vGBJSupport#  = ?.
    SET vSettingInsp#   = ?. 

    FOR EACH tmpl_list EXCLUSIVE-LOCK.
          DELETE tmpl_list.
    END. 

    FOR EACH tmpc_ctk EXCLUSIVE-LOCK.
        DELETE tmpc_ctk.
    END. 

    SET StatusCode = "".
END. /* END OF PROCEDURE */

It generates the warning too.
But this code doesn't
Code:
PROCEDURE doReset:
    SET vBatch_Par   = "".
    SET vBatch       = "".
    SET vTracebility = ?.

    SET vSettingWIP#  = ?. 
    SET vGBJSupport#  = ?.
    SET vSettingInsp#   = ?. 

    REPEAT :
        FIND FIRST tmpl_list EXCLUSIVE-LOCK NO-ERROR.
        IF AVAIL tmpl_list THEN DELETE tmpl_list.
        ELSE LEAVE.
    END. 

    REPEAT :
        FIND FIRST tmpc_ctk EXCLUSIVE-LOCK NO-ERROR.
        IF AVAIL tmpc_ctk THEN DELETE tmpc_ctk.
        ELSE LEAVE.
    END. 

    SET StatusCode = "".
END. /* END OF PROCEDURE */
I modified the FOR EACH with EXCLUSIVE-LOCK to a REPEAT with FIND FIRST. I drive the warning away. So what does it means? What's the difference between this two?
 

yoachan

Member
My third question:
If I had a code like this:

Code:
DO TRANSACTION :
    RUN doEverything.
END.

PROCEDURE doEverything:
    FOR EACH tbl_a EXCLUSIVE-LOCK.
        FIND FIRST tbl_b WHERE tbl_b.b_name = tbl_a.a_name
                         EXCLUSIVE-LOCK NO-ERROR.
        IF AVAIL tbl_b THEN SET tbl_b.b_qty = tbl_b.b_qty + tbl_a.a_qty.

        CREATE tbl_c.
        SET tbl_c.c_name  = tbl_a.a_name
              tbl_c.c_trans  = tbl_a.a_trans.
        SET tbl_a.a_qty = tbl_a.a_qty + 1.
    END.
END.

If my memory server me well, once I had an condition where tbl_c's creation failed because of it's UNIQUE index (I added record with same value so database reject it because it's already exist) because I hadn't check before creating tbl_c.
So if tbl_c's CREATE failed, the trasaction before and after (updating b and a) will be canceled, but why does the transaction for the next loop continuos? I wanted everything to be canceled. Not just current loop with error.

And what about this code below, is it differ from above?
Code:
DO TRANSACTION :
    RUN doEverything.
END.

PROCEDURE doEverything:
    DEF BUFFER bfr_a FOR tbl_a.
     FOR EACH tbl_a NO-LOCK.
         FIND FIRST tbl_b WHERE tbl_b.b_name = tbl_a.a_name
                          EXCLUSIVE-LOCK NO-ERROR.
         IF AVAIL tbl_b THEN SET tbl_b.b_qty = tbl_b.b_qty + tbl_a.a_qty.
 
         CREATE tbl_c.
         SET tbl_c.c_name  = tbl_a.a_name
               tbl_c.c_trans  = tbl_a.a_trans.
        FIND FIRST bfr_a WHERE ROWID(bfr_a) EQ ROWID(tbl_a)
                                EXCLUSIVE-LOCK NO-ERROR.
        IF AVAIL bfr_a THEN DO :
               SET bfr_a.a_qty = bfr_a.a_qty + 1.
               RELEASE bfr_a. 
        END.
    END.
 END.
My Regards

YoChan
 

TomBascom

Curmudgeon
I'm taking the rest of the week off so someone else will need to answer your questions...

For now I'll just say that the code shown is a "target rich environment".
 
Top