Hi COMMIT will forcefully write all the tranactions into Database. How the commit will work on the following situations ? Eg. I have modified some rows in “debitor” table in a processionOnly report. From this report I have called a codeunit and modified some values in table “calldetails” and say COMMIT within the codeunit. Is this commit will applied for only “calldetails” tables or Is Applied for both “debitor” and “calldetails” ? Regards Joseph Mathew
COMMIT is server side command. Server don’t know & don’t care about objects running on client side. COMMIT flush a session bufer to db.
Joseph, every modification during a write transaction (since the last commit) is committed. Don’t forget that there are implicit commits, e.g. when you call a codeunit like this OK := codeunit.run(…) Navision will commit your changes. If you do not want this and need a possible rollback in case of an error, use if codeunit.run(…) then… In the application designer guide you’ll find an appendix containing the report flowcharts. There you can see when the write transaction (BWT) in reports begins and ends (EWT). Torsten
Joseph, COMMIT will write all pending modifications/inserts/deletions to the database. Once done, they will NOT roll-back if an error occurs. So, in your case BOTH tables will be written using the COMMIT. As a general rule, I avoid COMMIT whenever possible. Bill Benefiel Manager of Information Systems Overhead Door Company billb@ohdindy.com (317) 842-7444 ext 117
No, that is not true! If you have a report that does some modifications, and then call a codeunit which also does some write transactions and a COMMIT then only the write transactions in the codeunit are COMMITted. This is because the codeunit does not know from which object it was called, and it issues it’s own BWT (Begin Write Transaction) and EWT (End WT) just as the report does. As a COMMIT forces the current write transaction to be committed, the COMMIT in the codeunit only writes the changes made in the codeunit to the database. Lars Strøm Valsted Head of Project and Analysis Columbus IT Partner A/S www.columbusitpartner.com
quote:
Originally posted by lstroem: If you have a report that does some modifications, and then call a codeunit which also does some write transactions and a COMMIT then only the write transactions in the codeunit are COMMITted.
NO. You are wrong. All objects modifications are maded to ONE BUFFER !!! To act like you telling, nf should create dofferent buffers for everyone object. What then about ERROR ? It rolls back only current obj modifications ? In this way after calling another obj you can’t see modifications maded by previous obj. Reasenly I have played with CFront with BWT/EWT. I tried to achieve behavior of EWT like you telling. Finished wthout success. Commit flushes different threads too !!! Indeed objects are ONLY SETS OF FUNCTIONS (pseudocode) and don’t have any mysteriuos code. Maybe more interesting is forms, which have commit OnFieldValidate, OnRecValidate and OnAfterCallAnotherObj.
quote:
Originally posted by lstroem: This is because the codeunit does not know from which object it was called, and it issues it’s own BWT (Begin Write Transaction) and EWT (End WT) just as the report does.
NO !!! Try imagine situation: Codeunit A makes modifications & calling Codeunit B Codeunit B makes modifications {You telling that now codeunit calls COMMIT} Codeunit couse ERROR. What will happen? COMMIT is issued ONLY BY CALLING OBJ, then call is executed !!! In nf calling obj can by ONLY FORM. Sure except then Commit included in obj. I don’t know maybe it posible in SQL db?
Well said Dalius! An example of this at work is codeunit 80. Early in the routine, the Use Invoice No. field is populated (if invoicing). The Sales & Receivables Setup table is modified & a commit is called. Later in the routine, the Post Item Journal Line routine, Post Gen. Jrnl Routine, etc are called. If an error occurs in ANY of those routines, the posting rolls back EXCEPT that the Use Invoice No. is still populated from prior to the commit. Bill Benefiel Manager of Information Systems Overhead Door Company billb@ohdindy.com (317) 842-7444 ext 117 Edited by - wbenefiel on 2001 Jun 27 22:04:35
so can i say that the coclusion to the topic is that, as soon as you commit, it is writing to the database, but most important of all, you cannot use navision’s roll back once you have COMMIT right? well that is because, currently i am writing a short function to insert records into the item journal with item tracking entries and do posting at the same time. the trick is, if the posting fails, there is not suppose to be any item journal lines in the item journal batch. all item journal lines inserted will have to be deleted. the item ledger entry posting procedure will use the commit function, and this will write the changes to the database, so i cannot roll back right? anyway, i have done something like this to handle the problem: IF NOT ItemJnlPost.RUN(ItemJnlLine) THEN ItemJnlLine.DELETE(TRUE); This code handles the portion where if the item journal line fails in posting, the item journal line will be deleted. but however, if i use IF NOT ItemJnlPost.RUN(ItemJnlLine) then this would prevent all the standard error messages that occur during posting from showing. an example of this error is when there is the same item with the same serial number. this error can onl be detected during posting. if i posted this using the coding that i have shown earlier, the user will not see the serial number error, but will see the standard error message that i have specified. is there anyway that i can show the navision standard posting errors and at the same time handle the posting it fails so that i can delete the failed item journal lines? tq in advance, jordan
Basically Lars is correct in what he has said. But it maybe needs some clarification. Take the following scenario. Create a table, and three code units.
Field No. Field Name DataType
1 Test Code10
2 Description Text30
CU1 (main)
OnRun()
IF CU2.RUN THEN
;
IF CU3.RUN THEN
;
MyTable.INIT;
MyTable.Test := '004';
MyTable.Description := 'End of Main';
MyTable.INSERT;
ERROR('Abort');
CU2 (sub 2)
OnRun()
MyTable.INIT;
MyTable.Test := '002';
MyTable.Description := 'Start of Sub 2';
MyTable.INSERT;
MyTable.TESTFIELD(Test,'LLL'); //creates an error
CU2 (sub 3)
OnRun()
MyTable.INIT;
MyTable.Test := '003';
MyTable.Description := 'Start of Sub 3';
MyTable.INSERT;
commit;
The result is that record 003 is created, but 002 is not and 004 is not. Try playing with this and trying different combinations of commit and errors, and you will understand what Lars was saying. _________________________ David Singleton Navision Consultant since 1991 dmks22@home.com___________ Edited by - David Singleton on 2001 Nov 06 05:10:47
Yes, if you use an If statement to IGNORE the fact that an error occured in CU2, it would work out as you have described. What I belive we (at least I) are getting at is that if you call any number of of codeunits and never use the IF and insted just CODEUNIT.RUN then when an error occures, it will roleback all changes since the last commit. Bill Benefiel Manager of Information Systems Overhead Door Company billb@ohdindy.com (317) 842-7444 ext 117 Edited by - wbenefiel on 2001 Nov 06 19:21:15
yup, thanks in advance for your replies… but i do know of the effect of COMMIT. My questions is when you use the codeunit below… IF CODEUNIT.RUN THEN … this will definitely cancel out any error messages that occur when the codeunit is run, but by structuring my code this way I am able to capture the return value of the codeunit, and should the codeunit fails in posting, i can do some processing. But i cannot have both. I cannot capture the return value of the codeunit when it is run, and at the same time not supressing all the error messages that occurred when running the codeunit. anyway, after consulting some friends, I have a solution as to how to determine the return value and at the same time not supressing the error messages that occurred when runnning the codeunit below: CODEUNIT 1 ---------- OnRun() res := FALSE; ERROR(‘This is a test error’); res := TRUE; CheckReturnVal() EXIT(res); CODEUNIT 2 ---------- OnRun() Codeunit2.RUN; IF Codeunit2.CheckReturnVal THEN MESSAGE(‘Successful!’) ELSE MESSAGE(‘Failed!’); Thanks.