Friday, September 23, 2016

SAP memory, ABAP memory and Shared Memory Object

  1. Various techniques to share the objects to memory

There are various techniques to share the objects to memory for processing the same data across different sessions. In SAP whenever we want to use data of one program to other or from one session to other session, we have to use any of the below techniques.

1.1  SAP memory

It is a Global memory available across all sessions.
SAP memory is a memory area to which all main sessions within a SAP GUI have access. You can use SAP memory either to pass data from one program to another within a session, or to pass data from one session to another.

Application programs that use SAP memory must do so using SPA/GPA parameters (also known as SET/GET parameters). These parameters can be set either for a particular user or for a particular program using the SET PARAMETER statement. Other ABAP programs can then retrieve the set parameters using the GET PARAMETER statement. The most frequent use of SPA/GPA parameters is to fill input fields on screens. The SPA/GPA parameters should be in TPARA table.

Syntax:

SET PARAMETER ID pid FIELD f.

This statement saves the contents of field f under the ID pid in the SAP memory.
Pid is name you specify for your memory id.

GET PARAMETER ID pid FIELD f.

GET PARAMETER ID 'WRK' FIELD P_WERKS.

This statement places the value stored under the pid ID into the variable f.
Pid is name you specify for your memory id.

A good example to understand SAP memory is when you save a SO or PO .
Go to VA03/ME23N you will see the latest SO /PO populated automatically in the screen  i/e through use of  SET and GET parameters in SAP std program.

The SAP memory is clear after you log out of the system.

1.2  ABAP memory

It is a local memory available within a session, works when internal sessions called in sequence.

ABAP memory is a memory area that all ABAP programs within the same internal session can access using the EXPORT and IMPORT statements.To pass data to a program which you are calling, the data needs to be placed in ABAP memory before the call is made. The internal session of the called program then replaces that of the calling program. The program called can then read from the ABAP memory. If control is then returned to the program which made the initial call, the same process operates in reverse.

IN FIRST INTERNAL SESSION
EXPORT T_TABLE TO MEMORY ID 'MY_ID'.
IN SECOND SESSION YOU CAN SAY...
IMPORT T_TABLE FROM MEMORY ID 'MY_ID'.

Limitation: Some times when a same user operates in different windows, data is not accessible which is encountered as different sessions.

1.3  Shared object memory

A shared memory technology where shared objects can be used by any of multiple users, applications, or program sessions with programming language support during development and at runtime. The developer can declare shared memory behaviours at design time to cause one or more area classes to be generated for use at runtime. A shared objects memory is managed by the runtime environment. Content is stored at runtime in an area instance of an area class. Class methods to be generated that include methods for attaching and detaching a running session to and from an area instance, and for detaching a session from a change request on an area instance with a commit or a rollback. The runtime environment manages locks for area instances.


2.  Implementation steps for Shared object memory


  • Create a Root Class that represents data structure for Area Class (Use SE80 or SE24)
  • Create a Shared memory area Class to wrap data class for standard shared memory object methods.This area is a  handler to handle the instances
  • ABAP code to Write data to shared memory object. This we will cover in the enhancement taking the reason for rejection and storing it in memory.
  • ABAP code to Read data from shared memory object. Since we have the reason for rejection data in our memory , we need to read it to cancel  the  PO and update SO.

2.1  Execution steps


Step 1. Creating a root class using SE24.

Root Class: The class whose instance, we will be storing in Shared object memory from our program. Any access to area instance is always through root instance. This class is same as any other global final class but should necessarily have a property called “Shared Memory Enabled” while creating.



Note : Mark the Check box Shared memory enabled, this helps to differentiate a shared memory root class.

i.) Define the attributes for the class - the data is going to be held by the class.


ii.) Define IF_SHM_BUILD_INSTANCE~BUILD:
This method is related to what is known as automatic pre-load (or auto-start) of the memory area related to our memory object. Basically, when a memory area is defined, we can explicitly set its properties so that it will be automatically initialized whenever an application tries to access it. Alternatively, if we do not define the memory area in this way, any access to it without the area having been initialized would trigger an exception of type CX_SHM_NO_ACTIVE_VERSION. Whatever we choose, we have to keep in mind that without automatic pre-load, our ABAP applications will have to check for existence of the memory area and initialize it manually if required. The automatic pre-load option removes this hassle by ensuring that any memory areas that are not yet initialized will be automatically started whenever an application tries to access the data. This means that if your ABAP program tries to read materials from the shared memory object, and the memory area hasn’t been initialized, it will be done “on the fly” – removing the need for handling the above exception in your applications.
Automatic pre-loading requires us to set a few parameters when defining the memory area (more on this in the next session – creating the memory area). It also means we have to add the interface IF_SHM_BUILD_INSTANCE to our root class.


iii.) Define the parameter for methods Set and Get to Read /Write the memory object respectively

 
iv.) Save and Activate the class.


Step 2: Create a new Memory Area for our shared object using SHMA transaction.

Memory Area : It is just a storage place in SOM space (Shared Object memory) you are defining for sharing your own objects like you get a parking space for your own vehicle. SAP differentiates every area by it’s attributes.

When we create an Area, automatically a related Area Class with same as of Area Name is generated. This class provides the methods for establishing a handle for the memory area (e.g. read, write, lock, ..). We can examine the class using transaction SE24 (it has the same name as the memory area):

 

i.) Observe one thing below, when you mark the check box, it enables versioning for the memory object example:

 
1 Instance 1 version
2 Instance 2 version

Area Instance Version/Versioning –  If a user is reading the contents of particular SOM instance and the writer also wants to write or update new contents in same instance, then a new version gets generated every time. Something is transit like old values, new values. There has to be always one version with which SOM runtime will work and just remember that a user always reads active/last committed version if there are multiple versions in SOM. Meanwhile if Writer has finished updating and if a new active version is now available, the old version will be automatically garbage collected by SOM runtime.

Now we all have a doubt, What if more than one user tries to write the SOM objects in the same memory area,
How to handle it ? Don’t worry we have something called SOM locks .

SOM Locks – If one writer is writing into same memory area instance, another user should not get access for writing again. When we perform a write in SOM, system will place a change lock, and hence no other writer can get the change access on the whole application server for same SOM instance.
On the other hand, Readers lock remains in effect till current session. Thus with the help of above property, the lock mechanism assures us to get the access to the active/most recent version every time.

Now we need to closely observe one thing, the class name which we give in constructor class gets dynamically defined and by default all methods are available.


2.3  How to use SOM in a program

In the above steps we learnt to design and define areas for our SOM. Now we can add the logic for export and import the objects in these areas.

For SOM, we require a handle to read/write object to the area, which is actually an ‘Instance of Area class. This handle is responsible to perform various tasks.

Area class is actually wrapper to hide the instances of Root class, which are written in SOM space. Now what we will use READ and WRITE instance methods of the class.

Let us take two instances: one Area handle and one root instance .The methods defined under Area handle will be used to place the Root instance in the SOM memory.

Don’t get confused, very simple. Please refer the below logic.


Step 3 and Step 4:

i.) Write to SOM Sample Logic

Define Area handle and Root instance.


Syntax:

Data:
Area_handle_name   TYPE REF TO area_name ,
Root_Instance_name TYPE REF TO root_class.

Area_handle_name  : Give any area name
Area_name        : Specify the area name you have created using SHMA

Root_Instance_name: Give any name for root
Root_class        : Specify the name of root class you have created.

Now get this Area handle instance and use it’s ATTACH FOR WRITE method, which is used to export our data to a SOM.


Syntax:

Area_handle_name = area_name => ATTACH_FOR_WRITE

  • Write the contents of Root class into SOM instance

  CREATE OBJECT Root_Instance_Name AREA HANDLE Area_handle_name.
Root_Instance_Name->name = `Welcome`.

“ Name is simple public attribute in root class

  • Specify to the Area handle that value is stored in which attribute of the Root.
        Area_handle_name->set_root(Root_Instance_Name).

  • Finally write the Root value to SOM
Area_handle_name->detach_commit( ).


Read from SOM Logic

DATA: Area_handle_name    TYPE REF TO  area_name,
Root_Instance_name  TYPE REF TO  root_class,
Display_SOM_Value  TYPE  string.

  • Get the handle through static method of Area Class ‘ATTACH_FOR_READ’

  • Area_handle_name = area_name => ATTACH_FOR_READ
  • Try catching exceptions while reading the SOM value.

  • Read the SOM value
  • Move Area_handle_name ->name to Display_SOM_Value.
  • Write : / Display_SOM_Value.  “ Normal write statement

  • After you are finished reading the value , release it .It may remove the read lock.
  • Area_handle_name->Detach().

This is how SOM can be used. We will understand some of Area class methods in more detail.


2.4 Understanding SOM predefined functions provided by SAP


1. Attach for Read : How to call this method   
 

ATTACH

This method enables read, write or update locks to be set at the same time on  area instances of one or more areas.

Ex : ATTACH_FOR READ , ATTACH_FOR_TEAM etc.


Whenever we call these methods for the instances , Don' forget to catch exceptions. There is a possibility of getting a read error / write error for the instance.

DETACH

This method releases the lock on the current area handle. The area handle is then inactive.
Exceptions
·     CX_SHM_WRONG_HANDLE
No read lock was active, but a change lock was (exception text: READ_HANDLE_REQUIRED)
·     CX_SHM_ALREADY_DETACHED
No read lock was active.
Both exception classes inherit from CX_DYNAMIC_CHECK.

We have many  detach methods available like:

DETACH_COMMIT.

DETACH_ROLLBACK.

When the DETACH_COMMIT method is called, the SHM_COMMIT_EVENT event of the generated area class is triggered automatically.

We need to have a handle to refer to the object whenever we try to read/write in a memory area.

DATA :lr_handle TYPE REF TO zsm_shma_cancel_po_area  Area Class
lr_root  TYPE REF TO zcl_shma_cancel_po_root Root attribute of handle            class.  
DATA :lw_area_name TYPE shm_inst_name. "SHM: Model of a Data Clas.


Sample Read from shared memory.

* called method to read the data from memory area
TRY.
CALL METHOD zsm_shma_cancel_po_area=>attach_for_read            EXPORTING
inst_name = lw_area_name
RECEIVING
handle    = lr_handle.
*  exception caught for inconsitency
CATCH cx_shm_inconsistent .
lf_readerror = 'X'.
*  exception caugt for inactive version
CATCH cx_shm_no_active_version.
lf_readerror = 'X'.
*  exception to check for read lock
CATCH cx_shm_read_lock_active .
lf_readerror = 'X'.
* exception to check parameter
CATCH cx_shm_exclusive_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_parameter_error .
lf_readerror = 'X'.
* exception to check
CATCH cx_shm_change_lock_active .
lf_readerror = 'X'.
ENDTRY.

In the above sample read, we have called a method of the class zsm_shma_cancel_po_area to read the memory object. There are certain exceptions caught if the object in the memory area is not ready for read operation. The above method helps us to handle those exceptions.

3. Problem statement to understand when to use SOM

In our Business process, Sales Order is created first, We get a Purchase Requisition and using that PR, RFQ  is created and for the confirmed RFQ’s PO is created. It is known as B2B process.

Whenever a SO line item is rejected in Sales Order by applying reason of rejection, for the corresponding item Std. SAP process deletes its PR. But if a PO exists for the SO, SAP doesn’t allow the user to change the SO until we manually delete that PO and later come back to SO for rejecting the line item. This process will explain implementation for the above requirement.

Requirement: We had a requirement to perform this task automatically i.e delete the PO in background and allow user to set the reason of rejection in SO.

Solution: The required functionality can be implemented with two approaches using Shared Object Memory or SAP Memory.

3.1  Analysis of the given requirement to develop a SAP solution

To start with the requirement: Let’s do some analysis.

Using Shared Object Memory

1. Firstly we will find the suitable enhancement spot to put our logic, For that it is always good to know the sales order user exit ( MV45AFZ ), this exit is called during SO creation (VA01) and SO change (VA02) transaction.

Now set a debugging point in Form ‘userexit_save_document_prepare’ which saves the SO related data.


Change your debugger settings by marking ‘Update debugging ‘


Mark the update debugging check box
Now go to VA02 , reject any SO line item.


  Here when we try to save the SO , system will populate an error message that a PO exits .We have to manually delete that PO  first, then only we can save the SO.


Now the above message you get when you save a SO, since our debugging is on, hit ENTER after putting reason for rejection. System will take us to this include FV45PF0V_VBAP-ABGRU_PRUEFEN.



2. In our analysis we found that VBAP-AGBRU is SET whenever we reject any material, it is linked to its subsequent documents i.e. PO. We understood one thing; if we clear VBAP-AGBRU system won’t give us an error message and allow us to save the sales document.

       i.) Find a Enhancement point for VBAP-ABGRU in the above include.

       ii.) Now Create an Implementation in the above Enhancement spot to take VBAP-AGBRU data to an internal table, once we successfully capture the reason for rejection data. Clear the VBAP-AGBRU data so that system allows the user to save the SO.

    Problem : We have reached some far but we have a problem. Do you think the data captured in internal table is really available.?

    Answer : No, we don’t have that data because of different sap sessions.

    SAP session :  A session is basically SAP instance where any code gets executed under a same task.

   Solution : There are three cross-program memory areas to which ABAP programs have access (refer to the diagram in                 Memory Structures of an ABAP Program) that you can use to pass data between programs.


3.2  Using Shared object memory functionality for the given requirement


Program code: This logic in the enhancement allows us to get the reason of rejection data and write it to sap shared memory, which we can use it later on for processing.

Pseudo Code:

1. Check if sales order is changed (sy-tcode = VA02) and reason for rejection is set by the user.
2. Check if a PO exists corresponding to this SO.
3. In the above step if a PO exists we can proceed to capture the rejection data to shared memory.
4. Attach for read method is used to check if the area from memory is available for read.
5. Now read the data from using GET method.
6. Attach for write method is called to write in the memory area.
7. Create a object using handle and root , SET method is executed to write the data.
8. Commit the work using detach.Commit() function and release the memory as well.

3.2.1 Steps to implement SOM for the custom requirement as per above pseudo code

Logic added in the enhancement we have found which is triggered when we enter the rejection data in SO.
Enhancement :
* Check sales order is changed
* and user has selected reason for rejection (VBAP-ABGRU) in SO line item
IF sy-tcode EQ 'VA02' AND
vbap-abgru IS NOT INITIAL.
*  Declaration
CONSTANTS: lc_funcname_29 TYPE rs38l bname VALUE'Z_MM_CANCEL_PO_ITEM',
lc_sapmv45a TYPE program_id VALUE 'SAPMV45A'.
DATA : gt_vbap TYPE TABLE OF vbap,
gst_vbap TYPE vbap,
gst_vbap1 TYPE vbap.
DATA: BEGIN OF gst_ekkn_tmp,
vbeln TYPE ekkn-vbeln,
vbelp TYPE ekkn-vbelp,
END OF gst_ekkn_tmp.
DATA : lr_handle TYPE REF TO z_class_shma_area1, " Area Class
lr_root  TYPE REF TO z_class_shma_root1. " Root attribute of handle class. SHM: Model of a Data Clas
DATA: lw_area_name TYPE shm_inst_name.
******************************************************
* First Try to Read
DATA excp TYPE REF TO cx_shm_no_active_version.
DATA lf_readerror TYPE c1.
**** First check if PO exists or not, then only proceed for deletion.
* Get data from EKKN table based on SO number
SELECT SINGLE n~vbeln n~vbelpFROM ekkn AS n INNER JOIN ekpo AS o
ON  n~ebeln = o~ebelnAND n~ebelp = o~ebelpINTO gst_ekkn_tmpWHERE n~vbeln EQ vbap-vbelnAND n~vbelp EQ vbap-posnrAND o~loekz EQ ''.
IF sy-subrc EQ 0.
TRY.
CONCATENATE 'VA02' vbak-vbeln INTO lw_area_name SEPARATED BY '-'.
* called method to read the data from memory area
TRY.
CALL METHOD z_class_shma_area1=>attach_for_readEXPORTING
inst_name = lw_area_name
RECEIVING
handle    = lr_handle.
*  exception caught for inconsitency
CATCH cx_shm_inconsistent .
lf_readerror = 'X'.
*  exception caugt for inactive version
CATCH cx_shm_no_active_version.
lf_readerror = 'X'.
*  exception to check for read lock
CATCH cx_shm_read_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_exclusive_lock_active .
* exception
lf_readerror = 'X'.
CATCH cx_shm_parameter_error .
lf_readerror = 'X'.
CATCH cx_shm_change_lock_active .
lf_readerror = 'X'.
ENDTRY.
IF  lf_readerror <> 'X'.
lr_handle->root->get_vbap_data( IMPORTING t_vbap_get = gt_vbap ).
lr_handle->detach( ).
ENDIF.
CATCH cx_shm_no_active_version INTO excp.
lf_readerror = 'X'.
ENDTRY.
IF lf_readerror = 'X'.
* lr_handle = z_class_shma_area1=>attach_for_write(  ).
TRY.
CLEAR lf_readerror.
CONCATENATE 'VA02' vbak-vbeln INTO lw_area_name SEPARATED BY '-'.
CALL METHOD z_class_shma_area1=>attach_for_writeEXPORTING
inst_name = lw_area_name
RECEIVING
handle    = lr_handle.
CATCH cx_shm_exclusive_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_version_limit_exceeded .
lf_readerror = 'X'.
CATCH cx_shm_change_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_parameter_error .
lf_readerror = 'X'.
CATCH cx_shm_pending_lock_removed .
lf_readerror = 'X'.
ENDTRY.
ELSE.
* lr_handle = z_class_shma_area1=>attach_for_update( ).
TRY.
CLEAR lf_readerror.
CONCATENATE 'VA02' vbak-vbeln INTO lw_area_name SEPARATED BY '-'.
CALL METHOD z_class_shma_area1=>attach_for_updateEXPORTING
inst_name  = lw_area_name*     attach_mode = CL_SHM_AREA=>ATTACH_MODE_DEFAULT
*     wait_time  = 0
RECEIVING
handle      = lr_handle.
CATCH cx_shm_inconsistent .
lf_readerror = 'X'.
CATCH cx_shm_no_active_version .
lf_readerror = 'X'.
CATCH cx_shm_exclusive_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_version_limit_exceeded .
lf_readerror = 'X'.
CATCH cx_shm_change_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_parameter_error .
lf_readerror = 'X'.
CATCH cx_shm_pending_lock_removed .
lf_readerror = 'X'.
ENDTRY.
ENDIF.
IF lf_readerror <> 'X'.

READ TABLE gt_vbap INTO gst_vbap WITH KEY vbeln = vbap-vbeln
posnr = vbap-posnr.
IF sy-subrc NE 0.

gst_vbap-vbeln = vbap-vbeln.
gst_vbap-posnr = vbap-posnr.
gst_vbap-abgru = vbap-abgru.
APPEND gst_vbap TO gt_vbap.
ELSE.
gst_vbap-abgru = vbap-abgru.
MODIFY gt_vbap FROM gst_vbap INDEX sy-tabix.
ENDIF.
CREATE OBJECT lr_root AREA HANDLE lr_handle.
lr_handle->set_root( lr_root ).
lr_root>set_vbap_data( t_vbap_set = gt_vbap ). "  custom SET method is executed
lr_handle->detach_commit( ).
IF fcode EQ 'SICH'.
CLEAR vbap-abgru.
EXIT.
ENDIF.
ENDIF.
ENDIF.
ENDIF.

Since we cleared the reason for rejection data and allowed the user to save the SO, we have to perform a background job and update the VBAP-AGBRU in the SO.

This is a different session, here we will try to read the AGBRU data stored in shared memory and use it for further processing. A new user exit on save is called: MV45AFZZ-USER_EXIT_SAVE_DOCUMENT.

** Check if it is a change in Sales Order

IF sy-tcode EQ 'VA02'.

DATA : lr_handle TYPE REF TO z_class_shma_area1,
gt_vbap TYPE TABLE OF vbap.
DATA : gst_vbap TYPE vbap.
DATA : lw_area_name TYPE shm_inst_name.
DATA excp TYPE REF TO cx_shm_no_active_version.
DATA lf_readerror TYPE c1.
CONCATENATE 'VA02' vbak-vbeln INTO lw_area_name SEPARATED BY '-'.
TRY.
CALL METHOD z_class_shma_area1=>attach_for_readEXPORTING
inst_name = lw_area_nameRECEIVING
        handle    = lr_handle.
CATCH cx_shm_inconsistent .
lf_readerror = 'X'.
CATCH cx_shm_no_active_version .
lf_readerror = 'X'.
CATCH cx_shm_read_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_exclusive_lock_active .
lf_readerror = 'X'.
CATCH cx_shm_parameter_error .
lf_readerror = 'X'.
CATCH cx_shm_change_lock_active." INTO excp.
lf_readerror = 'X'.
ENDTRY.
IF lf_readerror = 'X'.
WRITE: 'Could not read memory/No Change for Reason of Rejection'.
ELSE.
lr_handle->root->get_vbap_data( IMPORTING t_vbap_get = gt_vbap ).
lr_handle->detach( ).
READ TABLE gt_vbap INTO gst_vbap WITH KEY vbeln = vbak-vbeln.
IF sy-subrc EQ 0.
CONCATENATE sy-tcode vbak-vbeln 'Cancel PO' INTO l_name1 SEPARATED BY ':'.
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname          = l_name1
jobclass        = 'A'
IMPORTING
jobcount        = l_countEXCEPTIONS
cant_create_job  = 1
invalid_job_data = 2
jobname_missing  = 3
OTHERS          = 4.
IF sy-subrc = c_zero.
*** Get default printer
CLEAR usr01.
SELECT SINGLE spld FROM usr01INTO usr01-spldWHERE bname EQ sy-uname.
*** Get Spool authorization value
CLEAR usr05.
SELECT SINGLE parva FROM usr05INTO  l_authorityWHERE bname EQ sy-unameAND  parid EQ c_parid_sau.
IF sy-subrc NE c_zero.
CLEAR l_authority.
ENDIF.
CALL FUNCTION 'GET_PRINT_PARAMETERS'              "#EC *
EXPORTING
authority              = l_authority
destination            = usr01-spld
copies                = '1'
immediately            = c_checked
release                = ' '      "DON'T DELETE AFTER PRINT
new_list_id            = c_checked
no_dialog              = c_checked*  line_count         = sy-linct
*  line_size           = sy-linsz
IMPORTING
out_parameters        = l_params
valid                  = l_validEXCEPTIONS
archive_info_not_found = 1
invalid_print_params  = 2
invalid_archive_params = 3
OTHERS                = 4.
IF sy-subrc <> c_zero.
ENDIF.
* We will execute our report program in background to delete the PO.
SUBMIT zphsro01_cancel_po TO SAP-SPOOL
SPOOL PARAMETERS l_params
WITHOUT SPOOL DYNPRO
AND RETURN
VIA JOB l_name1 NUMBER l_countWITH p_vbeln    = vbak-vbeln.
IF sy-subrc <> c_zero.
*   MESSAGE i000 WITH text-er0.    
EXIT.
ENDIF.
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount            = l_count
jobname              = l_name1
strtimmed            = c_checkedEXCEPTIONS
cant_start_immediate = 1
invalid_startdate    = 2
jobname_missing      = 3
job_close_failed    = 4
job_nosteps          = 5
job_notex            = 6
lock_failed          = 7
invalid_target      = 8
OTHERS              = 9.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*     WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDIF.

Now our final aim is to set the PO deletion and Change the SO ( Set back the user’s reason of rejection data.This can be achieved by executing the report in background.

Pseudocode :

1. Attach for read the data from memory.
2. After reading get the data
3. Check for the corresponding SO
4. Get the PO
5. Lock both EBAN and VBAK table since the orders are being processed
6. Call BAPI_PO_CHANGE to set the deletion indicator in PO
7. Call BAPI_TRANSACTION_COMMIT to save the database
8. CALL BAPI_SO_CHANGE to change the SO
9. Call BAPI_TRANSACTION_COMMIT to save the database

REPORT PROGRAM

REPORT zphsro01_cancel_po MESSAGE-ID zhfe_zz.
*
START-OF-SELECTION.
** SOM code

CONCATENATE 'VA02' p_vbeln INTO gw_area_name SEPARATED BY '-'.
TRY.
CALL METHOD zcl_shma_cancel_po_area=>attach_for_readEXPORTING
inst_name = gw_area_name
RECEIVING
handle    = g_handle.
CATCH cx_shm_inconsistent .
g_readerror = 'X'.
CATCH cx_shm_no_active_version .
g_readerror = 'X'.
CATCH cx_shm_read_lock_active .
g_readerror = 'X'.
CATCH cx_shm_exclusive_lock_active .
g_readerror = 'X'.
CATCH cx_shm_parameter_error .
g_readerror = 'X'.
CATCH cx_shm_change_lock_active.
g_readerror = 'X'.
ENDTRY.
IF g_readerror = 'X'.
WRITE: 'Could not read memory'.
ELSE.
CLEAR g_readerror.
TRY.
g_handle->root->get_vbap_data( IMPORTING t_vbap_get = gt_vbap ).
g_handle->detach( ).
g_handle->free_instance( EXPORTING inst_name = gw_area_name ).
CATCH cx_shm_parameter_error .
g_readerror = 'X'.
CATCH cx_shm_wrong_handle .
g_readerror = 'X'.
CATCH cx_shm_already_detached .
g_readerror = 'X'.
ENDTRY.
CHECK g_readerror IS INITIAL.
CLEAR  gw_lock.
WHILE gw_lock IS INITIAL.

3.3  Using SAP memory for the given requirement         


Using SAP Memory ( Export to Database and Import to Database )

The approach, analysis remains the same , here we will use export to database and Import from database for writing the value to database and reading the value.

  • 1. Made a New Enhancement Implementation for the include which has been found in the above steps to capture the reason of rejection data.

FV45PF0V_VBAP-ABGRU_PRUEFEN : ZEI_SALES_CANC_PO

Program code  : Here we replace the Shared object memory code with SAP memory code ( EXPORT to database and Import to database concept )

****NOTE the syntax carefully for EXPORT TO DATABASE *****

     EXPORT gt_vbap_db[] TO DATABASE indx(zz)
FROM gst_indxCLIENT sy-mandtID vbak-vbeln.
*********** ********************
Created a FM and added inside USER_EXIT_SAVE_DOCUMENT of MV45AFZZ Program

** All piece of code is same as above, instead of using ATTACH FOR READ, we will use
IMPORT FROM DATABASE function.
Replace the import logic with the below code, remaining part submitting a background job logic is same as above.

** * Use of IMPORT TO DATABASE  Function ***

   IMPORT gt_vbap_db TO lt_vbap_db
FROM DATABASE indx(zz)
CLIENT sy-mandt
ID i_vbak-vbeln  .

IF sy-subrc EQ 0 .
*     'Data Read Successful!!'(m02) .
ELSE.
l_readerror = lc_checked.
ENDIF.
Remaining LOGIC is same

REPORT LOGIC

*****  Used Import/Export from/To database instead of Shared memory.
**** Use of IMPORT FROM DATABASE ******
IMPORT gt_vbap_db[] FROM DATABASE indx(zz) CLIENT sy-mandt ID p_vbeln .
IF sy-subrc EQ 0 .
MESSAGE 'Data read successfully!!'(m01) TYPE gc_s.
ELSE.
g_readerror = gc_checked.
ENDIF.
*** Once we have read the data successfully delete the data ****

DELETE FROM DATABASE indx(zz) CLIENT sy-mandt ID p_vbeln.


4. Comparison of using Shared object memory and SAP memory


When we compare the use of a Shared Memory Object to that of ABAP with Database read, the  below results show use of Shared Object Memory is 100 times faster than standard SAP DB read . However every approach cannot be fully best, Shared object has a drawback as well in a multiple server session, and sometimes it fails to get an instance.

4.1 Merits and Demerits: SOM and SAP memory


Shared object Memory
SAP Memory
High performance
Low Performance
Highly effective in single user session
Highly effective in multiple sessions
Memory utilization is very less
Memory utilization is more
          

4.2 Results after Implementation         

Memory utilization without use of SAP SOM
As expected, the DB load is completely removed when using shared memory objects. We can examine this by checking the run time analysis

Memory utilization with use of SAP SOM

When we observe here the ABAP use is more, however the database access is null, whereas the system load is somewhat higher than the classic ABAP program. Overall resource usage, is considerably less using the memory object.

No comments:

Post a Comment

SAP giới thiệu mã hỗ trợ AI trong ngôn ngữ ABAP riêng của mình

SAP đã ra mắt một loạt tính năng mã hỗ trợ AI trong môi trường phát triển ứng dụng dựa trên đám mây của mình, đồng thời tham gia vào danh sá...