IBM i Global

IBM i 

A space for professionals working with IBM’s integrated OS for Power systems to exchange ideas, ask questions, and share expertise on topics like RPG and COBOL development, application modernization, open source integration, system administration, and business continuity.


#Power


#IBMi
#Power
 View Only
  • 1.  Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Wed August 28, 2024 11:04 AM
    Edited by Agostino Sclauzero Wed August 28, 2024 11:33 AM

    I'm working on a stored procedure that performs a series of `INSERT` operations into various destination tables. Below is a simplified example of one of the tables involved:

        CREATE TABLE MY_DATA_TABLE (C1 INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, C2 TIME);

    The stored procedure also logs the actions performed in a dedicated log table:


        CREATE TABLE MY_LOG_TABLE (C1 INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, C2 TIME);

    The body of the stored procedure is as follows:


        BEGIN ATOMIC

            DECLARE X INT;

            INSERT INTO MY_DATA_TABLE (C2) VALUES (CURRENT TIME);    
            INSERT INTO MY_LOG_TABLE (C2) VALUES (CURRENT TIME);

            SET X = 1/0; -- Simulates an error    
        END;

    The transactional behavior is implemented using the `ATOMIC` clause of the `BEGIN...END` block, which handles the rollback in case of an error.

    **Problem:**

    With this approach, not only is the insertion into `MY_DATA_TABLE` rolled back in case of an error, but so are the insertions into `MY_LOG_TABLE`. However, I would like to preserve the log insertions since they are particularly useful when an error occurs.

    I found the following solution, which seems to work, but I'm not sure if this is a proper solution or if I'm just exploiting a side effect of an isolation clause, `WITH NC`, whose primary purpose is different so I expose myself to the risk of unwanted effects.


    BEGIN ATOMIC

        DECLARE X INT;

        INSERT INTO MY_DATA_TABLE (C2) VALUES (CURRENT TIME);
        
        INSERT INTO MY LOG_TABLE (C2) VALUES (CURRENT TIME) WITH NC;

        SET X = 1/0; -- Simulates an error
        
    END;



    ------------------------------
    Agostino Sclauzero
    ------------------------------



  • 2.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Wed August 28, 2024 03:38 PM

    Agostino, 

    The behavior is correct in the way you described on a basic level. 

    To Quote from the ItJungle Link (https://www.itjungle.com/2016/09/27/fhg092716-story02/) :

    The compound statement begins with BEGIN ATOMIC. This means that the entire compound statement is to be treated as a whole. If there were multiple database changes under commitment control, and one of them failed, all changes would be rolled back. In this case, a non-atomic statement would probably work just as well.

    If you were to add an exception handler that will always be called (in the case of a Div by 0) then it will not abide by the Atomic rules. 

    Here is an example:

    CREATE OR REPLACE PROCEDURE SCRATCH.TESTPROC ()
    LANGUAGE SQL

    P1: BEGIN
        
        declare sqlstate   char(5)       default '00000';
        declare ErrorMsg   varchar(96);


        DECLARE X INT;
        
        declare exit handler for sqlexception
          errorHndlr:begin


            INSERT INTO MY_LOG_TABLE (C2) VALUES (CURRENT TIME);
             set ErrorMsg = 'SQLSTATE=' concat sqlstate;
             signal sqlstate '99001'
                set message_text = ErrorMsg;


          end errorHndlr;
        
        P2: BEGIN ATOMIC

            INSERT INTO MY_DATA_TABLE (C2) VALUES (CURRENT TIME);    
            SET X = 1/0; -- Simulates an error    

        END P2;
        
    END P1;

    (Note: one can "nest" statements also to make the code more "streamlined") 

    HTH





    ------------------------------
    Marius le Roux
    Owner
    MLR Consulting
    ------------------------------



  • 3.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Wed August 28, 2024 05:17 PM

    Interesting, unfortunately this way i couldn't handle regular non-error log messages that would adhere to the atomic unit and thus in case of error I would lost part of the log information. 



    ------------------------------
    Agostino Sclauzero
    ------------------------------



  • 4.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Thu August 29, 2024 03:09 AM

    Inserting into the LOG File with WITH NC is exactly the way we handle (errors and other non-error messages we want to keep).

    Our software is running on multiple customer systems (but my manager does not want to install a deguggable version - customer could see the source code!!! Haha).

    If something happens the customers call ... you may imagine how exactly users can describe what happened. So we can look into the logfiles and see what happened.



    ------------------------------
    Birgitta Hauser
    Database and Software Engineer
    Selfemployed - Modernization-Education-Consulting on IBM i
    Kaufering
    +49 170 5269964
    ------------------------------



  • 5.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Thu August 29, 2024 08:10 AM

    Thanks, Birgitta, for your response!

    It's good to know that there is at least another team that use WITH NC in this way, but I'm curious-do you have any additional insights into how NC behaves? The documentation I found is pretty vague, and it seems almost paradoxical that "NO COMMIT" effectively means an immediate commit.

    Also, if you know of any additional resources or examples that could help me understand this better, I'd really appreciate it!



    ------------------------------
    Agostino Sclauzero
    ------------------------------



  • 6.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Thu August 29, 2024 08:50 AM

    It just means the statement where you added WITH NC does not run under commitment control. So a row which is inserted or updated without commitment control can be changed or deleted immediately, even though the current transaction is not yet terminated. Neither COMMIT nor ROLLBACK will effect the row.



    ------------------------------
    Birgitta Hauser
    Database and Software Engineer
    Selfemployed - Modernization-Education-Consulting on IBM i
    Kaufering
    +49 170 5269964
    ------------------------------



  • 7.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Thu August 29, 2024 03:11 PM

    This line from the documentation makes it clear that if you're using COMMIT(*NONE)/WITH NC that that those operations are not backed out.

    If an isolation level other then COMMIT(*NONE) was specified and the application issues a ROLLBACK or the activation group ends abnormally (and the commitment definition is not *JOB), all updates, inserts, deletes, and DDL operations made within the unit of work are backed out.

    FYI, there is a Power SQL Community for IBM i: ibm.biz/SQLonIBMi



    ------------------------------
    Kent Milligan
    ------------------------------



  • 8.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Fri August 30, 2024 06:31 AM
    Edited by Satid S Fri August 30, 2024 08:17 AM

    Dear Agostino

    >>>> do you have any additional insights into how NC behaves? The documentation I found is pretty vague, and it seems almost paradoxical that "NO COMMIT" effectively means an immediate commit. <<<<

    Does the document you read use the word "immediate commit" to explain WITH NC?  Is it IBM i document? 

    You should think of WITH NC as what it says "no commitment used".  When you run an SQL statement to change data without a commitment cycle active, the change goes directly to the data row in a table on disk (there are a few factors to prevent this but let's ignore them here for the sake of learning) - this is no commitment.    When commitment cycle is enable, all data changes under the cycle goes to memory buffer waiting for a COMMIT statement (or implicit commit) to be flushed to data row on disk or removed if ROLLBACK (explicit or implicit) is encountered instead.    In summary, WITH NC tells DB engine to put that specific data change directly to data on disk, not to memory buffer and wait for COMMIT or ROLLBACK.  

    Hope you get an idea. 



    ------------------------------
    Satid S
    ------------------------------



  • 9.  RE: Transaction Management in Stored Procedures: Is It Safe to Use 'WITH NC' to Preserve Log Insertions?

    Posted Thu August 29, 2024 05:23 AM
    Edited by Satid S Thu August 29, 2024 07:12 AM

    Dear Agostino

    >>>>BEGIN ATOMIC

        DECLARE X INT;

        INSERT INTO MY_DATA_TABLE (C2) VALUES (CURRENT TIME);
        INSERT INTO MY LOG_TABLE (C2) VALUES (CURRENT TIME) WITH NC;

    SET X = 1/0; -- Simulates an error
    END; <<<<

    I think that you should put INSERT INTO LOG_TABLE ...  WITH NC  before  INSERT INTO MY_DATA_TABLE.    The reason is that if somehow INSERT INTO MY_DATA_TABLE encounters an error, the rollback will happen and nothing will be inserted into your log table. 

    FYI, as of IBM i 7.4 (via TR PTF), there was a new SQL feature called SQL Error Logging Facility (SELF) that enables you to handle SQL error and warning more efficiently and its deployment is not complex. If you are interested in this, read more details here:  https://www.ibm.com/docs/en/i/7.4?topic=tools-sql-error-logging-facility-self.  And this blog post describes a subsequent enhancement to SQL SELF (also delivered by another TR PTF) that makes it more convenient to use:  https://www.rpgpgm.com/2024/01/self-improvement.html            

    SELF differs from the Db2 for i SQL Performance Monitoring or Database Monitoring feature in some significant ways:

    1. SELF is configured by the client to identify specific SQLCODE values that Db2 for i should use for SELF processing when a user-initiated SQL statement completes with a matching SQLCODE value.
    2. SELF collects point-of-failure information which is accessible through the QSYS2.SQL_ERROR_LOG view.
    3. SELF runs when an SQL statement completes with an SQLCODE value that matches a list of values in the SYSIBMADM.SELFCODES built-in global variable.
    4. SELF is safe to use in production environments. It has no performance impact to SQL statements that complete successfully or for any SQL errors or warnings where the SQLCODE does not match the values listed in the SYSIBMADM.SELFCODES global variable.



    ------------------------------
    Satid S
    ------------------------------