IT干货网

ABAP-锁机制

sanshao 2022年03月09日 SAP 154 0

转载:IT虾米网

SAP 锁机制、sap锁机制简单理解sm12

SAP锁机制

一、SAP为什么要设置锁:
1,保持数据的一致性
如果几个用户要访问同样的资源,需要找到一种同步访问的方法去保持数据的一致性。比如说,在航班预订系统中,需要检查还有没有空座位,当检查的时候,你不想别人修改重要的数据(空座位的数量)。
2,仅仅用Database锁是不够的
数据库管理系统物理锁定了要修改的行记录,其他用户要等到数据库锁释放才能访问这个记录。在SAP系统中,当一个新屏幕显示的时候会释放掉Database锁,因为屏幕的改变会触发一个隐式的DB COMMIT。如果数据是从好几个屏幕收集来的话,而且在这段时间内这些数据会分别被锁定,仅仅用Database锁就不够了。 SAP系统在应用服务器层面有一个全局的LOCK TABLE,可以用来设置逻辑锁来锁定相关的表条目,并有ENQUEUE工作进程来管理这些锁。SAP锁是一种逻辑意义上的锁,有可能你锁定的表条目在DATABASE上根本就不存在。

二、锁对象和其对应的Function Module
在SE11里创建锁对象,自定义的锁对象都必须以EZ或者EY开头来命名。一个锁对象里只包含一个PRIMARYTABLE,可以包含若干个SECONDARY TABLE,锁的模式有三种:E,S,X。LOCK PARAMETERS里填写你要根据哪些字段来锁定表条目。
模式E:当更改数据的时候设置为此模式。WriteLock(exclusive lock)
模式S:本身不需要更改数据,但是希望显示的数据不被别人更改。Read Lock(Shared Locked)
模式X:和E类似,但是不允许累加,完全独占。Enhancedwrite lock (exclusive lock without cumulating)
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为E,其他用户不能再对这个锁对象加E、X、S模式的任意一种锁;
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为X,其他用户不能再对这个锁对象加E、X、S模式的任意一种锁;
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为S,其他用户不能再对这个锁对象加E、X模式的锁,但是可以加S模式的锁;
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为E,在这个程序,你还可以再对这个锁对象加E、S模式的锁,X模式的不可以。
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为X,在这个程序,你不可以再对这个锁对象加E、X、S模式的锁。
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为S,在这个程序,你还可以再对这个锁对象加S模式的锁,如果没有别的用户对其加S模式的锁,那么你还可以对其加E模式的锁。X模式的不可以。
当激活锁对象的时候,系统会自动创建两个FM,ENQUEUE_<锁对象名>和DEQUEUE_<锁对象名>,分别用来锁定和解锁。

SAP Provide three type of Lock objects.

• ReadLock(Shared Locked)

protects read access to an object. The readlock allows other transactions read access but not write access to

the locked area of the table

• WriteLock(exclusive lock)

protects write access to an object. Thewrite lock allows other transactions neither read nor write access to

the locked area of the table.

• Enhancedwrite lock (exclusive lock without cumulating)

works like a write lock except that theenhanced write lock also protects from further accesses from the

same transaction.

三、锁定和解锁
当用逻辑锁来锁定表条目的时候,系统会自动向LOCK TABLE中写入记录。
当调用设置锁的FM时,LOCK PARAMETERS如果没有指明,系统会锁定整个表。当然,LOCK PARAMETER:CLIENT有点特殊,如果不指定,默认是SY-MANDT;如果指定相应的CLIENT,会锁定对应CLIENT上的相应的表记录;如果设置为SPACE,则锁定涉及所有的CLIENT。
当逻辑锁设置失败后,一般会有两种例外。一个是EXCEPTION:FOREIGN_LOCK,意思是已经被锁定了;另一个是EXCEPTION:SYSTEM_FAILURE。有些情况下,程序中设置成功的逻辑锁会隐式的自己解锁。比如说程序结束发生的时候(MESSAGE TYPE为A或者X的时候),使用语句LEAVE PROGRAM,LEAVE TO TRANSACTION,或者在命令行输入/n回车以后。
在程序的结束可以用DEQUEUE FUNCTION MODULE来解锁(当然如果你不写这个,程序结束的时候也会自动的解锁),这个时候,系统会自动从LOCK TABLE把相应的记录删除。使用DEQUEUE FUNCTION MODULE来解锁的时候,不会产生EXCEPTION。要解开你在程序中创建的所有的逻辑锁,可以用FM:DEQUEUE_ALL.


四、上锁的一般步骤
先上锁,上锁成功之后,从数据库取数据,然后更改数据,接着更新到数据库,最后解锁。按照这个步骤,才能保证更改完全运行在锁的保护机制下。

关于仓库管理的录屏程序涉及到mb1b之后做tr转to,估计是tr表被SAP锁机制给锁定了,如果延迟 
时间不够,就会报错:TR正在被处理。 
我用FUNCTION 'DEQUEUE_ELLTBKE'解锁之后,TR转TO可以操作了,但是却依然报错。实在想不出 
原因。求助!~

Try adding a "commit work" in the middle of theprocess.

SAP锁机制针对数据库层和应用服务层都上锁了,我用函数只是把 
应用服务层给解锁了,数据库层要用COMMIT WORK来解吧。

锁定主要是基于数据库的要求。很多表在数据库层是不可见的,所以对于锁的管理,要在SAP界面上来完成。锁一种叫共享的锁,一种叫排它的锁。

事务代码:SM12,共享下面有X的,是共享的锁。是表明不许别人改,但是可以看。

排他的锁,是不许别人看和修改。

缺省支持13000条锁。锁的资源在内存中的一个表locklist,如果都填满的话,那就锁定失败,就不能更改,没有锁的资源了。

别人已经锁定的情况下,自己的就不能锁定了。

以上都是正常的锁定。

还有一种情况是“死锁”;die log,比如a用户,b用户都要用1-4进程,a用户用1,2,b用户用3,4,那么大家都占用自己的资源,都等待别人放开锁。

盘点要把所有的用户都锁定住。

事务代码:DB01,看死锁。

锁定要发送一个命令去锁,还要发一个命令去解锁。比如锁掉了以后,机器就down了,或者网络断了,也就出现了锁掉了,没有解锁。用事务代码sm12,手工去删除掉。

死锁是对系统性能比较严重的一个问题。

锁掉还有一种情况,就是有些动作是不能够同时做的。

凡是更改数据库,就一定会有锁定。

耗时间:SD反冲,价格,ATP CHECK

MMPP,MRP RUN

CO:物料帐

来做lock是通过enqueue server的。如果是在应用服务器上的话,要通过message server来传送到CI的。如果lock太多的话,内存表有预定义大小的,想办法减少lock的数量(有一个技术叫“锁升级”),想办法增加lock table的大小(增大内存)。通常SAP是行锁定,只锁一行或者某些行。在数据库,lock table也是有限的。锁升级也就是用一个锁,把这个表锁掉。表锁定有一个参数来控制的,当一个用户锁掉超过70%了,那就把这个表锁定,可以减少锁掉表的总数。

如果一个用户发了一条命令,如果dialog突然断掉,或者用户退出,没有人解锁。那么就需要系统管理员来参与。事务代码:SM12,看锁定的时间,三个小时以上就可以查明原因。那么还有一个事务代码,DB01,正常是NO lock.

也可以给用户权限,可以删除自己的lock。

sap锁机制简单理解

由于工作的需要,最近在研究业务系统数据并发控制问题,曾经写过abap程序,记得sap里有个锁对象,可以对表记录进行锁定操作,于是进行了相关了解,并在此基础上设计了基于MC的锁机制(有时间再献上基于MC的锁机制,供大家批判)。如果觉得下文所述,似曾相识,说明大家对sap所对象的理解已经超越我。

sap为了同步同时多个用户操作同一数据,防止数据出现不一致性而采用了锁机制。一般 sap会在操作数据前设置锁,防止第二个用户进行修改操作,当操作结束后系统会自动释放锁(当然程序也可以调用解锁函数去解锁)。

1、SAP锁的类型

1)Exclusive lock

The locked data can be read orprocessed by one user only. A request for another exclusive lock or for ashared lock is rejected.

2)Shared lock

Several users can read the same dataat the same time, but as soon as a user edits the data, a second user can nolonger access this data. Requests for further shared locks are accepted, evenif they are issued by different users, but exclusive locks are rejected.

3)Exclusive but notcumulative lock

Exclusive locks can be requested bythe same transaction more than once and handled successively, but an exclusivebut not cumulative lock can only be requested once by a given transaction. Allother lock requests are rejected.

2、TCODE、相关表、多表锁

1)TCODE:可以通过se11来查看和创建锁对象,锁对象创建完毕之后,统会自动创建两个FM,ENQUEUE_<锁对象名>和DEQUEUE_<锁对象名>,分别用来锁定和解锁。

2)相关表:

DD25L:组合标题(方式,MC目标,锁定目标)(纪录了锁主表);

DD25T:

DD26S:视图的基本表和外来码关系(纪录了所有和锁相关的表);

DD27S:合计(视图,MC对象,锁定对象)字段;

3)多表锁

在SE11里创建锁对象,自定义的锁对象都必须以EZ或者EY开头来命名。一个锁对象里只包含一个PRIMARY TABLE,可以包含若干个SECONDARYTABLE。如多表锁:EMEKKOE,主表:EKKO-->E 专用累积,从表:EKPO-->E专用累积。

3、锁的生命周期

通常程序一运行就要对特殊记录进行ENQUEUE处理,程序运行完毕之后进行DEQUEUE处理(不显示处理的话,关闭该session的时候,sap会自动DEQUEUE,此处sap真N!)。

4、锁的作用范围

sap锁仅对特定程序起作用,假设A程序改table1的第1条记录,B程序也改table1的第1条记录,A程序一运行就对table1的第1条记录加锁,B程序则未加锁,则B程序仍可以改table1的第1条记录内容。

se11的最后一个功能是建立锁对象,例如对创建的数据库表加锁,命名可以是“E”+表名(这块有的帐户权限可能不够建不了,找basis给权限吧)。
名字起好后点创建,输入锁对象短文本(描述),在tables选项中选择要加锁的表名,之后在下面的lock parameter中一般选择“E”(专用,累积),设置好后,一个锁对象就建好了,在lock parameter选项中,系统默认表的所有主键都是锁参数。根据个人需要可以删除不需要的参数
之后在程序中,调用CALL FUNCTION ‘ ENQUEUE_EZMATMOV ‘和CALL FUNCTION ‘ DEQUEUE_ EZMATMOV ‘两函数在程序中加锁和解锁,第一个函数用于在程序操作数据库之前上锁,后一个是程序操作数据库后将锁释放。代码如下:

 1 data: l_mqid like ZMM_MES_MATM_LOG-MQID, 
 2 l_sentti like ZMM_MES_MATM_LOG-SENTTI, 
 3 l_USERID like ZMM_MES_MATM_LOG-USERID, 
 4 l_BWART like ZMM_MES_MATM_LOG-BWART. 
 5 data: l_errmsg(255). 
 6 CALL FUNCTION ‘ENQUEUE_EZMATMOV’ 
 7 EXPORTING 
 8 mode_zmm_mes_matm_log = ‘E’ 
 9 mandt = sy-mandt 
10 mqid = l_mqid 
11 sentti = l_sentti 
12 userid = l_userid 
13 bwart = l_bwart 
14 * x_mqid = ’ ’ 
15 * x_sentti = ’ ’ 
16 * x_userid = ’ ’ 
17 * x_bwart = ’ ’ 
18 _scope = ‘219 * _wait = ’ ’ 
20 * _collect = ’ ’ 
21 EXCEPTIONS 
22 foreign_lock = 1 
23 system_failure = 2 
24 OTHERS = 3. 
25 IF sy-subrc <> 0. 
26 * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO 
27 * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 
28 * into l_errmsg. 
29 * write: / l_errmsg. 
30 MESSAGE e001(z001) WITH ‘多个用户不能同时对数据做操作处理!‘. 
31 EXIT. 
32 ENDIF. 
33 select zpesinfnr…. 
34 35  
36 CALL FUNCTION ‘ DEQUEUE_ EZMATMOV ‘ 
37 EXPORTING 
38 mode_zpseinfnr = ‘E’ 
39 mandt =sy-mandt 
40 .

附件是截图

最后在SE37中可以去看系统已经帮我们自动生成的锁定和解锁的函数。详细可以参考ENQUEUE_EZMATMOVDEQUEUE_EZORDCFM,所建的锁定和解锁的函数都放在叫/1BCDWBEN/ZEN0000的函数组中

SAP中锁对象的删除

在sap中当你打开一个transaction时,你想再打开另外一个一样的transaction是不被允许的,因为有锁对象的存在,但是也有办法来删除该锁对象,使多个用户对一个transaction进行操作

T-Code:SM12

代码:

DATA: lt_enq_del TYPE STANDARD TABLE OF seqg3, 
lt_enq_read TYPE STANDARD TABLE OF seqg7, 
lw_enq_read TYPE seqg7, 
lw_enq_del TYPE seqg3, 
lv_subrc TYPE sy-subrc.

1. Read all the lock details in system

CALL FUNCTION 'ENQUE_READ2' 
EXPORTING 
gclient = sy-mandt 
gname = ' ' 
guname = '*' 
TABLES 
enq = lt_enq_read.

2. We will search entry for table level lock for our table

LOOP AT lt_enq_read INTO lw_enq_read 
WHERE gname EQ 'RSTABLE' 
AND garg CS 'ZOPS_PROFILE'. 
 
MOVE-CORRESPONDING lw_enq_read TO lw_enq_del. 
APPEND lw_enq_del TO lt_enq_del. 
ENDLOOP.

3.Delete table level lock entry for our table

CALL FUNCTION 'ENQUE_DELETE' 
EXPORTING 
check_upd_requests = 1 
IMPORTING 
subrc = lv_subrc 
TABLES 
enq = lt_enq_del.

评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

ABAP-DB/SAP LUW