Unexpected COMMIT

hxrhxr Member Posts: 20
I want to share with you situation I have faced where unexpected commit occurs. (Maybe it’s not a bug, and this is how Navision works. So commit was unexpected only for me :) but anyway...

Nav sp3, SQL.
There is a form with button. In that’s button OnPush trigger I write a following code.
Repeatedly run report which changes some records. When first time report runs, I run it with request form, where user can enter a few parameters. After report has run, I take chose parameters and on next iterations (2nd , 3rd and so on) I run the same report without request form by passing chose parameters to report by function. (Another words – without user interaction).
Problem – looks like commit occurs after first iteration. For ex. If some records were changed after first iteration, but on second or next iterations occurred error – records which were changed on first iteration (when request form was shown) stays – not rolls back, but second and other iteration changes disappear – rollback works.
I hade to change my code and set parameters on the form (textboxes etc.) before running report. So I pass chose parameters to report by function and run report without request form. In this case everything works as it should, if error occurs all changes roll back.
“bad” Code example:
CLEAR(recCopy);
recCpy.COPY(Rec);
recCopy.FINDFIRST;
   REPEAT
     i += 1;
     IF i = 1 THEN BEGIN
       CLEAR(rep);
       rep.RUNMODAL;
       //Here commit occurs. Even if error appears on further iteractions chese changes stay.
       rep.GetJournal(lcTempl, lcBatch);
     END ELSE BEGIN
       CLEAR(rep);
       rep.USEREQUESTFORM(FALSE);
       rep.SetJournal(lcTempl, lcBatch);
       rep.RUNMODAL;
      END;
   UNTIL recCopy.NEXT = 0;

Question,
Do the same problem appears if I use “OK := Codeunit.RUN” instead of “rep.RUNMODAL” ?

Comments

  • ara3nara3n Member Posts: 9,256
    Turn on code coverage and see if there is any code that has a COMMIT.


    IF CODEUNIT.RUN then does commit.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • kinekine Member Posts: 12,562
    I am sure that you will find out that there is some explicit commit in the process which is called in the report itself... ;-)
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • hxrhxr Member Posts: 20
    I did everything you wrote. There is no commit!

    Then, tell me why commit occurs only on the first iteration? If there is an error on second and other iterations, all changes roll back, but changes made after first iteration always stay.

    When I run report without request form rep.USEREQUESTFORM(FALSE) and error occurs, then all changes stay unsaved.

    I think, Navision after running RUNMODAL report with request form, finishes transaction and it does not matter if that report was run in a loop or etc.

    BTW, if I lock table before running report I get standard Navision error that report.RUNMODAL and Ok:=CODEUNIT.RUN cannot be run in modify operations, and I must make commit or change programs structure.
  • kinekine Member Posts: 12,562
    You cannot use Report.RUNMODAL with requestform when there is running transaction... ;-) if you try it, you will get big error message...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • ara3nara3n Member Posts: 9,256
    The requestform is a form, and as mentioned above if you run a form modal during transaction you'll get the error, but I want to add that if you close a form, it COMMITS anything you've modified.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • rdebathrdebath Member Posts: 383
    To find an unexpected commit create a record variable for any table then add:

    Barrier.CONSISTENT(FALSE);

    This will cause any commit, including the implicit ones at the end of triggers to throw the huge error.

    Just before you expect the COMMIT turn it off...

    Barrier.CONSISTENT(TRUE);

    You can also add these in a single instance codeunit:
    VAR Barrier Record 15;
    VAR BarrierFlag Boolean;
    
    SetBarrier(TurnOn : Boolean)
        BarrierFlag := TurnOn;
        Barrier.CONSISTENT(NOT BarrierFlag);
    
    GetBarrier() : Boolean
        EXIT(BarrierFlag);
    

    Then use this to disable a commit sometimes.

    IF FeelLikeIt THEN Barrier.SetBarrier(TRUE);
    .
    .
    .
    IF NOT Barrier.GetBarrier THEN COMMIT;
    .
    .
    .
    Barrier.SetBarrier(FALSE);
Sign In or Register to comment.