Shared Memory-enabled Classes and Create Data – Area Handle
Summary
Shared Objects are objects in the shared memory. The shared memory is a memory area on an application server, which is accessed by all of this server’s ABAP programs. In this article I am giving a brief idea on Shared Memory-enabled Classes, ‘Create Data – Area Handle’ statement and read/write of shared objects. Sufficient screenshots and sample codes are also provided.
Author: Abyson Joseph Chavara
Company: Applexus Technologies (P) LTD
Created on: 02 April 2012
Introduction
Shared Objects are objects in the shared memory. The shared memory is a memory area on an application server, which is accessed by all of this server’s ABAP programs. Before shared objects were implemented, ABAP programs could access this memory area using the EXPORT and IMPORT statements exclusively, but this method was very slow because the “sending” program had to copy variables from its memory to the shared memory, and the “receiving” program had to copy these variables from the shared memory into its own program memory. This generated two copies for basically nothing. With the implementation of shared objects with Release 6.40, the shared memory was enhanced with the shared objects memory that stores shared objects. Shared objects are stored in what are called shared memory areas. You create and manage areas and their properties using Transaction SHMA.
The benefits of shared objects includes Copy-free: very fast access, version management, preloading, automatic propagation from a database, easy monitoring, etc. In this article I am giving a brief idea on Shared Memory-enabled Classes, ‘Create Data – Area Handle’ statement and read/write of shared objects. Sufficient screenshots and sample codes are also provided.
Shared Memory-enabled Classes
The prerequisite for storing an instance of a class in the shared memory is that the class of the object has to be defined with the SHARED MEMORY ENABLED addition of the CLASS statement, or that the property Shared memory-enabled has to be selected in the Class Builder. Each area is linked with what is called a global area root class, which can contain separate data and references to other instances of shared memory-enabled classes or to anonymous data objects in its own attributes.
Area Classes and Area Handles
When an area is defined in Transaction SHMA, a global and final area class with the same name is generated as a subclass of CL_SHM_AREA. Class CL_SHM_AREA itself is a direct subclass of CL_ABAP_MEMORY_AREA. In an ABAP program, an area is accessed exclusively using the methods of the generated area class. There are static methods for binding an ABAP program (or its internal session) to area instances in the shared memory (attach methods). Binding creates an instance of the area class as an area handle, and creates a lock at the same time. The ABAP program can access the bound area instance version using the area handle and thus access the shared objects that are stored there. The area handle also contains the methods for deleting the connection or the lock (detach methods).
CREATE DATA – AREA HANDLE
This statement creates an anonymous data object as shared object in the area instance version of the shared memory, which is bound to the area handle referenced by handle. For handle, an object reference variable must be specified; whose static type is CL_ABAP_MEMORY_AREA or one of its subclasses (area class). When the statement is executed, handle must point to an area handle and the area handle must be bound to an area instance version with a change lock. To create such a reference, you have the following options:
- Transfer of the return value of the methods ATTACH_FOR_WRITE or ATTACH_FOR_UPDATE of an area class created with SHMA.
- Transfer of the return value of the method GET_HANDLE_BY_OREF of any area class.
- Transfer of the return value of the method GET_IMODE_HANDLE of the predefined class CL_IMODE_AREA.
The latter is a reference to an area handle for the current internal mode and the statement CREATE DATA acts like without the addition AREA HANDLE.
Example 1
Here is a very simple example showing the steps to create the root class, shared area, and the use of CREATE DATA – AREA HANDLE statement.
Step 1: Creating Root class
First of all we have to create a Root class. Go to SE24 and create a new class. Here I have given the name ‘ZCL_SHR_AREAHANDLE_ROOT’. Go to the properties tab and check the box Shared Memory -Enabled, as shown in the below image.
Step 2: creating attributes
Now go to the attributes tab and create 2 attributes. Here I have named as ‘id_num’, level as instance attribute, visibility as public, associated type as STRING and second one named as ‘dref’, level as instance attribute, visibility as public, associated type as DATA (for Area Handle). See image below.
Step 3: Assign Interface.
Go to the tab interface and assign the interface “IF_SHM_BUILD_INSTANCE” and activate the class.
Step 4: Creating Area (SHMA)
Now run transaction SHMA and create a area named ‘zcl_shr_areahandle_area’. Give ‘zcl_shr_areahandle_root’ as root class and constructor class. Check the box ‘Aut. Area Creation’ and ‘With Versioning’. Select ‘Displacement Not Possible’ for ‘Displacem. Type’ field and ‘Autostart for Read Request and Every Invalidation’ for ‘Area Structure’ field. Screen shot shown below.
Step 5: attach_for_write( )
Now go to SE38 and create a program, for eg. ‘ZCL_SHR_AREAHANDLE_SET’. After creating an area handle referenced from ‘v_area_handle’, an instance of the area root class ‘zcl_shr_areahandle_root’ of the area is created. In area root class, we have already created a generically typed (using REF TO data) data reference variable named ‘dref’ as public attribute. With CREATE DATA, you create an anonymous data object in the area instance version, which is fed with a value after it has been assigned to a field symbol. The sample code is given below.
REPORT zcl_shr_areahandle_set.
DATA: v_area_handle TYPE REF TO zcl_shr_areahandle_area,
v_root TYPE REF TO zcl_shr_areahandle_root.
FIELD-SYMBOLS <fs_data> TYPE ANY.
TRY.
v_area_handle = zcl_shr_areahandle_area=>attach_for_write( ).
CREATE OBJECT v_root AREA HANDLE v_area_handle.
v_area_handle->set_root( v_root ).
*dref is the attribute created in root class.
CREATE DATA v_root->dref AREA HANDLE v_area_handle TYPE string.
ASSIGN v_root->dref->* TO <fs_data>.
<fs_data> = ‘700’.
v_area_handle->detach_commit( ).
CATCH cx_shm_external_type.
CATCH cx_shm_attach_error.
ENDTRY.
Step 6: attach_for_read( )
We can access the shared object, in another program. For that, create another program in SE38 named for eg. ‘zcl_shr_areahandle_get’. Sample code given below.
REPORT zcl_shr_areahandle_get.
DATA v_area_get TYPE REF TO zcl_shr_areahandle_area.
FIELD-SYMBOLS <fs_get> TYPE ANY.
TRY.
v_area_get = zcl_shr_areahandle_area=>attach_for_read( ).
ASSIGN v_area_get->root->dref->* TO <fs_get>.
WRITE:/ <fs_get>.
v_area_get->detach( ).
CATCH cx_shm_attach_error.
ENDTRY.
You can see the output as displayed below.
Example 2
In the next example we will add two methods to the root class, for writing and reading values to the shared object.
Step1: Adding methods
Go to the methods tab of the root class. You can see method ‘IF_SHM_BUILD_INSTANCE~BUILD’ is added automatically. Create two more methods named ‘GET_ID_NUM’ and ‘SET_ID_NUM’. Set the level and visibility attributes as shown in the image below.
Step 2: Adding parameters to methods
Add a parameter l_msg to the method ‘GET_ID_NUM’, type as Returning, as shown below.
Also add a parameter l_id_num to the method ‘SET_ID_NUM’, type as Import, and associated type as string.
Step 3: Area constructor
Double click on the method ‘IF_SHM_BUILD_INSTANCE~BUILD’ and add the following code between the ‘method IF_SHM_BUILD_INSTANCE~BUILD’ and ‘endmethod’ statements and save.
DATA: sh_area TYPE REF TO zcl_shr_areahandle_area,
sh_root TYPE REF TO zcl_shr_areahandle_root.
* Get a pointer to shared area
sh_area = zcl_shr_areahandle_area=>attach_for_write( ).
* Create an instance of the root
CREATE OBJECT sh_root AREA HANDLE sh_area.
* Sets Intial values
sh_root->set_id_num( ‘999’ ).
* set the root back into the area
sh_area->set_root( sh_root ).
* Commit and detach
sh_area->detach_commit( ).
Step 4: Adding code lines in Methods.
Double click on the method ‘SET_ID_NUM’ and enter the following code between ‘method SET_ID_NUM’ and ‘endmethod’ statement and save.
id_num = l_id_num.
Next double click on the ‘GET_ID_NUM’ method and enter the following code between ‘method GET_ID_NUM’ and ‘endmethod’ statement, then save and activate.
DATA: lv_id_msg TYPE string.
* Concatenating a title to id_num.
CONCATENATE ‘Identification Number:’ id_num
INTO lv_id_msg.
l_msg = lv_id_msg.
Step 5: ‘attach_for_update( )’
Now we are going to set values to the memory by using the method ‘attach_for_update’. (Remember we have already initialized the id_num using method ‘attach_for_write’ in the Area Constructor.) Go to SE38 and create a program named for eg. ‘zcl_shr_areahandle_update’ and enter the following code and execute.
REPORT zcl_shr_areahandle_update.
DATA: v_area TYPE REF TO zcl_shr_areahandle_area,
v_root TYPE REF TO zcl_shr_areahandle_root.
TRY.
v_area = zcl_shr_areahandle_area=>attach_for_update( ).
CATCH cx_shm_no_active_version.
WAIT UP TO 1 SECONDS.
v_area = zcl_shr_areahandle_area=>attach_for_update( ).
ENDTRY.
v_root ?= v_area->get_root( ).
IF v_root IS INITIAL.
CREATE OBJECT v_root AREA HANDLE v_area.
ENDIF.
v_root->set_id_num( ‘800’ ).
v_area->set_root( v_root ).
v_area->detach_commit( ).
Step 6: ‘ attach_for_read ( )’
Now we can read the memory from another program. Go to SE38 and create a new program named for eg. ‘zcl_shr_areahandle_read’ and enter the following code and execute.
REPORT zcl_shr_areahandle_read.
DATA: v_area1 TYPE REF TO zcl_shr_areahandle_area.
TRY.
v_area = zcl_shr_areahandle_area=>attach_for_read( ).
CATCH cx_shm_no_active_version.
WAIT UP TO 1 SECONDS.
v_area = zcl_shr_areahandle_area=>attach_for_read( ).
ENDTRY.
DATA: v_msg TYPE string,
l_msg TYPE string.
v_msg = v_area->root->get_id_num( ).
WRITE: / v_msg.
v_area->detach( ).
You can see that v_msg will print the previously updated value ‘800’ along with the concatenated string ‘Identification Number:’
Related Content
http://help.sap.com/saphelp_nw70/helpdata/en/c5/85634e53d422409f0975aa9a551297/content.htm
http://help.sap.com/abapdocu_70/en/ABAPCREATE_DATA_AREA_HANDLE.htm
http://help.sap.com/saphelp_nw70/helpdata/en/df/109b8b4b073b4c82da0f2296c3a974/content.htm
NIce, Nice, very Nice 🙂
This is what I looked for 🙂
Thanks you very much.
Good One 🙂
With this functionality, you can include Persistent class concept too. But good job maachu!!
Good Job 🙂 .
Great Job.
Highly informative....
Interesting Post !
Helpful...
interesting
Good One indeed !!
Dear Abyson
Thanks for sharing knowledge
Really Good one.
But i think u have also create document
Parallel processing
with it until it's not helpful
Thanks
Mohit
hi,
Nice to read your blog. It’s useful and impressive. Thanks for sharing. 🙂
Thanks for the post.
Thanks
Hi, Nice post..just one doubt, which method to call for freeing up allocated memory.
hi, sorry anyway got it its free_instance, thanks once again
Very nice!
Thank you!
I am still confused about the use of this class. Previously we were using export ...Import.
One alternative of export import could be the use of function group. Suppose we want the value of variable a (inside called program) to be reflected in calling program then we can use the following approach. Create one function module to set the global variable and create another function module to get the global variable. This can be used instead of export and import. Please explain me what is the advantage of your approach so that we can implement it.
Regards,
Sucheta.
Hi,
The advantages would be that you can store an entire object with all it's attributes (an entire program execution) that anyone could read. Even more you can you can store the data for a longer period of time, unrestricted by your internal session lifetime.
And you have the ability to manipulate the Area by setting a lifetime, version, client dependency and a constructor class.
Good tip
Hi,
well explained.
Thanks
Thanks for the good tutorial! I am trying to store an instance of a class the shared memory, is this not possible?
I keep getting an error (storing lr_ref_tu), even though simple string values work (1234):
gr_area = zcl_area=>attach_for_write( ).
DATA lr_zc_hu TYPE REF TO zcl_hu.
IF gr_share IS INITIAL.
CREATE OBJECT gr_share AREA HANDLE gr_area TYPE zcl_hu.
ENDIF.
gr_area->set_root( gr_share ).
CREATE OBJECT gr_share->gr_oref AREA HANDLE gr_area TYPE zcl.
lr_zcl_hu ?= gr_share->gr_oref.
lr_zcl_hu->set_te_buffer( ir_ref_tu = lr_ref_tu ).
lr_zcl_hu->set_num( if_num = '1234' ).
Thank You!
This helped a lot!
BR