1. SMO 介绍
Shared Object,并不是一个新的技术,相反在SAP中已经应用了非常多的地方(可以通过SHMM中去查看,会得到很多你意想不到的东西);它作为SAP共享与传递数据的一个point,同ABAP/SAP Memory一样,但是目前它仅用于instance of class,并不能存任何的data.
Shared object(或者说instance更合适)存在于shared memory中,而该memory的大小是由abap/shared_objects_size_MB profile paramete所决定的。我们可以很容易地使用SHMM来管理并控制它,例如display/change/delete等。
其中shared object与shared memory又是通过shared area联系起来的,它可以通过SHMA来管理。Area在SHM/SMO中是非常重要的概念,它是建立在其上的vesion instance的template,如果设置允许,它可以有多个instance并可以具有不同的状态state,它在design时需要设置一个root class也就是shared object.
一个class要被设置成为shared object in shared memory,那么其必须在其attribute上勾选上shared memory enabled.
当在SHMA中定义了一个area,那么一个global and final class将作为cl_shm_area(它是cl_abap_memory_area的子类)的子类被自动创建.外部的abap程序通过Area handle来该问area instance version从而也就访问了shared object的数据.
同时每一次access到area instance version,都会产生一个对应的lock;
对于锁,SMO中具有以下特点:
Read Lock(读锁)
读锁在一个Internal session中最多只能有一个read lock,而对于multi session可以有多个read lock;它的解锁使用detacch; Read Lock一般是设在active area instance version.
Write Lock(写锁)
在一个application server上最大只能有一个write lock for an area instance,同时其他锁不可再加;
同时每一次access到area instance version,都会有一个相关的state of area instance version;
对于state有以下的几种状态:
(1) Build
一个area instance version有write lock时,它自动就是build;
(2) Active
当遇到detach_commit后,这个area instance version就是active了.注意:上面也说到了,所有的read lock都是设置在该上面的.
(3) Obsolete
当另一个new version完成并active了(注意:此时要么无锁,要么只能是read lock),那么当前的这个active version就obsolete了(也可使用invalidate instance/area),当然前面的这个version上的read lock会一直到它结束,以后的read lock就会自动设置在这个新的active instance version.
(4) Expired
这时,当Obsolete的version上的所有read lock都结束了,这个version就expired.它会被垃圾处理器处理掉.
另外,注意:
(1) 如果这个area是without version的,那么它只能有一个area instance version,所以它只能是上面的这四个state中的一个;
(2) 如果这个area是with version的,那么它可能会有多个area instance version:
因为write lock:所以它最大只能有一个的version是build
最大只能有一个是active version
可能有多个obsolete version;
可以通过以下的方法取得Area Handle:
· ATTACH_FOR_WRITE
· ATTACH_FOR_UPDATE
· ATTACH_FOR_READ
· Multi_ATTACH:注它可以同时创建多个handle.
产生的Area handle都对应着一个Area Instance version, 同时会产生lock.
其中ATTACH_FOR_WRITE :
如果lock允许的话, 产生一个Area Instance version;同时还可以指定其name,这样一个area就可以有多个instance(每个instance都会有自己的version),如果没有Name指定,那么将使用CL_SHM_AREA=>DEFAULT_INSTANCE;
所以建议,使用特定的name, 当这个binding(area handle=>area instance version)存活间, 都可以对该area instance version进行修改;
将产生一个change lock;
ATTACH_FOR_UPDATE
如果lock允许的话:
如果area with version: 那么将copy active area instance version
如果area without version,那么将Bind (area handle=>active area instance version)
同write一下,可以赋一个name,如果没有的话,则使用CL_SHM_AREA=>DEFAULT_INSTANCE;
将产生一个change lock;
ATTACH_FOR_UPDATE
如果lock允许的话:
将Bind (area handle=>active area instance version)
同write一下,可以赋一个name,如果没有的话,则使用CL_SHM_AREA=>DEFAULT_INSTANCE;
将产生一个Read lock;
可以通过以下的方法取得解除Area Handle与Area instance version间的bind:
· DETACH
· DETACH_COMMIT
· DETACH_ROLLBACK
· DETACH_AREA 与DETACH_ALL_AREAS:用于一次解除多个bind
以上的方法都同时会release lock.
· DETACH : removes a read lock.
· DETACH_COMMIT :removes a change lock by confirming the changes that were made.
· DETACH_ ROLLBACK: removes a change lock without confirming the changes that were made.
另外还具有一些很有用的方法:
Invalidating Version:
· Invalidate_instance
· Invalidate_area
这些方法可以防止另一个read lock来设置,哪怕即使已存在一个read lock.
Delete Version:
· Free_instance
· Free_area
这些方法将所有的lock解掉,并将instance给expired,所以,后续任何的锁都不可再加.
Get Area Instance information :
· Get_instance_infos
这将得到该Instance的信息到一个内
.
Get Area Handle information :
· Get_lock_kind
· Is_valid
· Is_active_version
· Has_active_properties
· Get_detach_info
这将得到该lock以及state of area-handle.
另外build方法作为consturctor method of area也是非常有用的.
同时,我们在得到了area handle后,我们必须再用它来与root class进行联系起来:
每一个area instance version必须有一个root class;我们可以得到root class的reference,通过调用handle的root的attribute.
当write lock在detach_commit后,我们需要使用Handle的set_root将root class联接起来.
更多Shared object可以参阅SAP Help:
2. SMO 实例
在下面的实例中,我们的需求是:
Program 1: Report,负责取得数据,然后传递给shared area;
Program 2: Report,从shared area中取得数据并展示出来;
这样的需求非常常见,也可以将其视为job的两个step或者WD中的多个task。因为我们program 1中产生的数据是”临时”的,所以,不希望通过DB或者其他memory等方式来保存这些临时数据;
(1)创建Root Data Class
Root data class即是我们需要保存数据或instance的class。它是后面创建shared area的必须;
Tcode:SE24
首先需要在property下勾选share-memory enable
定义两个global data(就是需要shared的data)
其中GT_MEMBER的类型为table type of 表zt_member.
然后进入定义Method
注:这里仅实现parse_write_data
它的实现:
参数
IV_CL_IDTYPEINT4
methodPARSE_WRITE_DATA.
IFIV_CL_IDisINITIAL.clear:gv_msg.CONCATENATE‘NoClassIDInput’‘Time:’sy-UZEITintogv_msgSEPARATEDBYspace.else.*Retrievedataclear:GT_MEMBER.SELECT*fromZTB_MEMBERintotableGT_MEMBERwhereID=IV_CL_ID.IFsy-subrc=0.clear:gv_msg.CONCATENATE‘Retrevedatasuccessfully!’‘Time:’sy-UZEITintogv_msgSEPARATEDBYspace.else.clear:gv_msg.CONCATENATE‘Retrevedatafailed!’‘Time:’sy-UZEITintogv_msgSEPARATEDBYspace.ENDIF.ENDIF.
endmethod.
(2)创建Shared Area