2008 Nov 25 9:11 AM
I use FM 'Number_get_next' to generate next number. Yet, I want to update number range once the record is successfully commit Updated. If the record is not commited, the number range should not b eupdated. Please tell me solution or is there any other FMs should I use before real update for the number range?
Please give kind help on this.
Many thanks in advance
2008 Nov 25 9:18 AM
Hi Amit,
The number range object is also saved in DB table NRIV
if your transaction fails to update or you dont want the number to be used and reset the number back to the previou value
write a select query on NRIV table it always holds the latest number reduce it by one or ( according your requirement. )
like
nrlevel = nrlevel - 1.
and update the NRI Table
Hope this will serve your purpose.
Regards
Ramchander Rao.K
2008 Nov 25 9:15 AM
I think NUMBER_GET_NEXT does not send a COMMIT WORK, so you should be able to ROLLBACK WORK later without DB update.
It would be pretty simple for you to try it out and confirm with a small program.
Thomas
2008 Nov 25 9:18 AM
Hi Amit,
The number range object is also saved in DB table NRIV
if your transaction fails to update or you dont want the number to be used and reset the number back to the previou value
write a select query on NRIV table it always holds the latest number reduce it by one or ( according your requirement. )
like
nrlevel = nrlevel - 1.
and update the NRI Table
Hope this will serve your purpose.
Regards
Ramchander Rao.K
2008 Nov 25 9:22 AM
I don't think this is a good idea, there might be several parallel processes accessing the same number range, there is number range buffering...you could create severe problems by directly updating NRIV.
Thomas
2010 Mar 24 7:14 PM
Hi Amit,
at the end of the LUW, an implicit database commit is executed. The LUW ends with the next possible user input, in background with end of program.
That means, an error message or a screen interaction (popup) will end the LUW and trigger the implicit commit.
If you detect an error after calling NUMBER_GET_NEXT, you can execute statement ROLLBACK WORK. This will clear the rollback segment and all database changes done during the LUW are deleted.
I learned the negative aspect of this behavior this week: A custom program drew a number for an object to be created. After saving the object to database, a foreign-lock-check stopped the process and caused a rollback.
Not leaving the transaction, the foreign lock was removed by an other user and the save was tried again, this time seemingly successful. The number drawn in the first try was used but the database record was not created again.
Later we detected, that the object was missing in the database but the number had been drawn again for another object.
Before we had this error, we did not expect that it is possible to call NUMBER_GET_NEXT and get the same number again. Now we know: Explicit COMMIT WORK helps:-)
Regards,
Clemens
2010 Mar 24 7:34 PM
2010 Mar 24 8:12 PM
Assign a temporary number like '000000000$'. Get the number only when you're certain of commitment, or (like the rest of SAP), recognize that there will always be gaps because the get_number routine updates that number range. Rolling it back by subtracting one could be very problematic, since it will ENSURE that there are attempts to duplicate document numbers.
2010 Mar 24 10:18 PM
Unfortunately, ROLLBACK has no effect on NUMBER_GET_NEXT as there is an explicit database commit when SAP takes a number. Note that there is a mechanism to only affect NRIV (and related number range tables), not the other updates.
In fact, NUMBER_GET_NEXT reserves definitely the number(s).
So, you should use NUMBER_GET_NEXT only when you are sure that the update will be done, usually during the update task, the latest possible (which is often not possible).
Note that because of some legal requirements, it may be needed to provide a program which lists all skipped numbers (SAP explains that in many notes).
Read that: [sap library - how number range buffer works|http://help.sap.com/saphelp_nw2004s/helpdata/en/95/3d5540b8cdcd01e10000000a155106/frameset.htm]
2010 Mar 25 12:02 PM
Hi Sandra,
>
> Unfortunately, ROLLBACK has no effect on NUMBER_GET_NEXT as there is an explicit database commit when SAP takes a number.
This seems not to be true, at least not in our ECC600 system:
FORM number_get_next .
DATA:
lv_num type char10.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01'
object = '/RPG/CO_CN'
IMPORTING
number = lv_num
EXCEPTIONS
OTHERS = 0.
WRITE: / 'number drawn', lv_num.
WRITE: / 'roll back'.
ROLLBACK WORK.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = /rpg/co_cl_cust=>data-cnt_nrrangenr
object = /rpg/co_cl_cust=>cnt_nrrange
IMPORTING
number = lv_num
EXCEPTIONS
OTHERS = 0.
WRITE: / 'number drawn', lv_num.
ENDFORM. " NUMBER_GET_NEXT
gives result
number drawn 2000003415
roll back
number drawn 2000003415
But you are righr, and this was also our solution: First do all required steps and immediately before updating the database, as last action, call the NUMBER_GET_NEXT.
Regards,
Clemesn
2010 Mar 25 12:36 PM
Hi Clemens,
Thx for the feedback, you're right, I'm completely wrong, sorry for that! I had worked on previous release R/3 4.7 and I was pretty sure there was a commit, but it seems not.
I made a few tests, the commit works whatever the number range buffer type is.
Sandra
2010 May 29 3:06 PM
HI:
I think Sandra's comment is right. Maybe something related with number range buffer.
The example for " FM number_get_next -> roll back -> FM number_get next" NRIV is just called by one FM and immediately rollback.
You can try to test SAP transaction(e.g. posting MIRO to Accounting, and do the rollback in FM AC_DOCUMENT_POST in BTE event 1050) many number range object like "COPA_OBJ", "RE_BELEG", "ML-BELEG"," RF_BELEG" will not rollback .
2010 Sep 24 12:28 AM
"ROLLBACK WORK" worked in my code.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = lc_nrrange " ls_t003-numkr
object = lc_rf_beleg
subobject = iv_comp_code
toyear = iv_fisc_year
IMPORTING
number = lv_belnr
EXCEPTIONS
interval_not_found = 1
number_range_not_intern = 2
object_not_found = 3
OTHERS = 4.
IF sy-subrc <> 0.
PERFORM get_error_from_system.
ENDIF.
cv_subrc = sy-subrc.
IF g_post_check = abap_true.
ROLLBACK WORK.
ENDIF.
CONCATENATE lv_belnr iv_comp_code iv_fisc_year INTO cv_obj_key.
2012 Oct 19 10:42 AM
Hello All,
I've been also recently strugling with rollback of 'next number' and I think it's worth to explicetely mention that rollback works only for non-buffered(!) number ranges.
As far as buffered number ranges are concerned the assigned numbers are written to the database immediately (as per documentation posted by Sandra).
Best regards,
Zigi
2015 May 13 8:20 AM
Hi All,
writing this to help someone who comes here in search of help. I know the thread is very old.
I faced similar issue while working with CO01 - Create Production Order. Originally, when we create the order then system generates serial numbers automatically (each for that many number of pieces ordered) but business wants to generate custom serial numbers which would be concatenation of a prefix string (6 letters) + numbers generated from number range ILOA.
I used the exit - EXIT_SAPLIPW1_001. Here, i could generate numbers (using number_get_next) successfully and upon saving the order (as a positive test) things looked fine.
However, if the user comes out of transaction choosing not to save the order (as a negative test) then the serial numbers generated would not revert!!! This created gap in serial numbers!!
As a working solution, In the exit EXIT_SAPLIPW1_001, I would fetch NRLEVEL from NRIV (bypassing buffer) and generate as many numbers by simple increment and save the latest number in memory id (use Export memory id). I would NEVER call number_get_next here.
We also need to implement another exit - EXIT_SAPLCOBT_001. Here, we need to import memory id for recent number generated in previous exit and fetch NRLEVEL from NRIV table once again (yes, you get same number as in previous exit). Just take the difference : Recentmost Number from memory id - (minus) NRIV-NRLEVEL. Now,call number_get_next in Do n times where n is the difference just derived ( ignore_buffer = 'X'). Dont forget to free memory id at the end of all this.
If user saves the order then the serial numbers are generated and committed inside the second exit. If user does not save the order then second exit is not called and number_get_next is not executed and thus NRLEVEL remains in correct state.
I got this idea when i debugged standard code. I understood it this way, implemented and it worked for me! I will update if any issues arise.
Meanwhile, kindly let me know if anyone is anticipating an issue with this logic.
Regards,
Jayaprakash