锁机制相关(一)_SAP刘梦_新浪博客

一、SAP锁的概念

SAP 的锁是一种逻辑锁,SAP为了同步同时多个用户操作同一数据,防止数据出现不一致性而采用了锁机制。一般SAP会在操作数据前设置锁,防止第二个用户进行修改操作,当操作结束后系统在释放锁。

二、SAP为什么要设置锁

1.保持数据的一致性

如果几个用户要访问同样的资源,需要找到一种同步访问的方法去保持数据的一致性。比如说,在航班预订系统中,需要检查还有没有空座位,当检查的时候,你不想别人修改重要的数据(空座位的数量)。

2.仅仅用Database锁是不够的

数据库管理系统物理锁定了要修改的行记录,其他用户要等到数据库锁释放才能访问这个记录。

SAP Lock是一种逻辑锁,相对于DB Lock,是一种轻量级的锁,DB Lock一旦发现不能加锁会进行延迟等待,使用SAP Lock 一定程度上可以减少对DB Lock的占用,避免死锁,同时合理使用SAP Lock可以保证数据的一致性

在SAP系统中,当一个新屏幕显示的时候会释放掉Database锁,因为屏幕的改变会触发一个隐式的DB COMMIT。如果数据是从好几个屏幕收集来的话,而且在这段时间内这些数据会分别被锁定,仅仅用Database锁就不够了。

SAP系统在应用服务器层面有一个全局的LOCK TABLE,可以用来设置逻辑锁来锁定相关的表条目,并有ENQUEUE工作进程来管理这些锁。SAP锁是一种逻辑意义上的锁,有可能你锁定的表条目在DATABASE上根本就不存在。

 

注:select for update 是在DB层次上加的锁

三、锁对象和其对应的FM

在SE11里创建锁对象,自定义的锁对象都必须以EZ或者EY开头来命名。一个锁对象里只包含一个PRIMARY TABLE,可以包含若干个SECONDARY TABLE,锁的模式有三种:E(Exclusive lock),S(Shared lock),X(Exclusive but not cumulative lock)。LOCK PARAMETERS里填写你要根据哪些字段来锁定表条目。

模式E:当更改数据的时候设置为此模式。

Exclusive lock :The locked data can be read or processed by one user only. A request for another exclusive lock or for a shared lock is rejected.

模式S:本身不需要更改数据,但是希望显示的数据不被别人更改。

Shared lock :Several users can read the same data at the same time, but as soon as a user edits the data, a second user can no longer access this data. Requests for further shared locks are accepted, even if they are issued by different users, but exclusive locks are rejected.

模式X:和E类似,但是不允许累加,完全独占。

Exclusive but not cumulative lock :Exclusive locks can be requested by the same transaction more than once and handled successively, but an exclusive but not cumulative lock can only be requested once by a given transaction. All other lock requests are rejected.

如果你在一个程序里成功对一个锁对象加锁之后,如果模式为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_<</span>锁对象名>和DEQUEUE_<</span>锁对象名>,分别用来锁定和解锁。

四、锁定和解锁

当用逻辑锁来锁定表条目的时候,系统会自动向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.

五、上锁的一般步骤

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

六、SAP锁的相关知识

1.相关TCODE:SE11

2.相关表

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

DD25T: 视图和锁定对象的短文本

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

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

3.相关函数

RS_DD_ENQU_EDIT

RS_DD_ENQU_ADD

 

4.获取表相关锁的列表程序

REPORT  ZLM_TEST LINE-COUNT 70

                 LINE-SIZE  255

                 NO STANDARD PAGE HEADING.

type-pools: slis.

tables: DD02L,dd26s.

data: begin of g_tab occurs 10,

  TABNAME like dd26s-TABNAME,

  VIEWNAME type dd26s-VIEWNAME,

  ename like EMFIN-FBEMFIN,

  dname like EMFIN-FBEMFIN,

end of g_tab.

data g_fcat  type slis_t_fieldcat_alv.

data:  g_fieldcat type slis_fieldcat_alv.

select-options s_table for dd02l-TABNAME default 'VBAK'.

end-of-selection.

  select dd26s~TABNAME dd25l~VIEWNAME

  INTO CORRESPONDING FIELDS OF TABLE g_tab

  from dd26s

  inner join dd25l

    on dd26s~VIEWNAME = dd25l~VIEWNAME

       and dd25l~AGGTYPE = 'E'

    where TABNAME in s_table.

  loop at g_tab.

    concatenate 'ENQUEUE_' g_tab-VIEWNAME into g_tab-ename.

    concatenate 'DEQUEUE_' g_tab-VIEWNAME into g_tab-dname.

    modify g_tab.

  endloop.

 

  call function 'REUSE_ALV_FIELDCATALOG_MERGE'

    EXPORTING

      i_program_name     = 'ZTEST4'

      I_INTERNAL_TABNAME = 'G_TAB'

      i_inclname         = 'ZTEST4'

    CHANGING

      ct_fieldcat        = g_fcat.

 

  g_fieldcat-fieldname = 'ENAME'.

  g_fieldcat-seltext_s = '加锁函数名'.

  append g_fieldcat to g_fcat.

 

 g_fieldcat-fieldname = 'DNAME'.

  g_fieldcat-seltext_s = '解锁函数名'.

  append  g_fieldcat to g_fcat.

 

  call function 'REUSE_ALV_GRID_DISPLAY'

    exporting

*      i_callback_program       = repname

*      i_callback_user_command  = g_user_command

*      i_structure_name         = 'INV'

*      is_layout                = layout

       it_fieldcat              = g_fcat

*      is_variant               = g_variant

*      it_events                = events[]

*      i_callback_pf_status_set = 'F01_ALV_EVENT_PF_STATUS_SET'

    tables

      t_outtab                 = g_tab.

 

5.通过断点找程序所用到的锁

用se38打开程序LSENAF01,并定位到send_enqueue子过程,在该过程中的任一语句设置断点。完成断点设置后,则去执行标准tcode,系统就会在程序调用锁时自动停止在断点处,这时你就可以通过调用堆栈获取加锁函数(ENQUEUE_XXXXXX),其中"XXXXXX"就是锁名称,你就可以通过SE11查看锁信息。

 

6 锁相关的函数

DEQUEUE_ALL  Release Locks of an LUW(释放当前LUW的所有锁)

7 如何对表加锁

CALL FUNCTION'ENQUEUE_E_TABLE'

EXPORTING

  MODE_RSTABLE ='E'

  TABNAME ='Table Name'

* VARKEY =

* X_TABNAME = ' '

* X_VARKEY = ' '

* _SCOPE = '2'

* _WAIT = ' '

* _COLLECT = ' '

 EXCEPTIONS

   FOREIGN_LOCK = 1

   SYSTEM_FAILURE = 2

   OTHERS = 3

          .

IF sy-subrc = 0.

 WRITE: 'Lock table successfully!'.

 else.

  write: 'Failed'.

ENDIF.

 

七、锁对象(Lock Object)和 FM(Function Module)
激活锁定对象时,产生的 FM 的名字是什么?

答案:首先要在 ABAP 字典中创建锁对象,然后才能在 ABAP 程序中设锁。创建锁对象时,系统会自动生成两个 FM 来进行锁管理。

用于设锁的 FM 为: ENQUEUE_<</span>锁对象名>。它用于在锁表(Lock Table)中生成一个锁项(Lock Entry)。若设锁不成功的话,就会在 Return 中反映出来。

用于释放锁的 FM 为:DEQUEUE_<</span>锁对象名>。它用于从锁表中删除一个锁项。在 ABAP 程序中,只需使用 "CALL FUNCITION ..." 语句就可以调用它们。这两个锁 FM 是在 SAP 系统的一个特殊工作进程中执行的,专门进行锁管理。它运行在一个单独的服务器上,而该服务器专门用于维护整个 SAP 系统的主锁表(Central Locak Table)。

八、加锁和解锁FM的一些参数

scope 参数: 1 表示程序内有效, 2 表示 update module 内有效, 3 表示全部有效。

_wait 表示如果对象已经被锁定,是否等待后再尝试加锁,最大的等待时间 有系统参数 ENQUE/DELAY_MAX控制。

_COLLECT 参数表示是否收集后进行统一提交,COLLECT 是一种缓存与批处理方法,即如果指定了Collect,加锁信息会放到Lock Container 中,Lock Container实际上是一个funciton Group控制的内存区域,如果程序中加了很多锁,锁信息会先放到内存中,这样可以减少对SAP锁管理系统访问,若使Lock Container中的锁生效,需执行FLUSH_ENQUEUE 这个Funciton,将锁信息更新到锁管理系统中,此时加锁操作生效,使用函数RESET_ENQUEUE可以清除Lock Container中的锁信息。

释放锁:调用DEQUEUE函数

如果程序更新用到到V1 Update时,在commit work是会删除所有的锁


最后关于加锁时
scope 参数:1 2 3特做测试后的补充。

对于最终的效果,scope = 1 和 scope = 3是一样的。
    在调用加锁函数时,锁加上,SM12可查到。

中间无论是调用其他FM,还是调用BAPI,及时使用了commit work。

锁依然存在,SM12一直可以查,

直到调用了解锁函数,锁才能解掉,【在SM12里消失】。


如果 scope = 2.

如果加锁后,使用了 in up date task 模式调用了FUNCUNTION 。

则锁就进入了更新进程里【目前执行程序在dialog进程里】

如果调用FM后,使用了commit work。
    则锁自动解【SM内消失】


但是!

如果 scope = 2.

就是正常的dialog或者Report,中间没有调用 in up date task模式【或同等效果的】

则此锁还在dialog进程里。

commit work不会解锁

只有调用解锁函数才能结。


综上:调用的时候就是用scope = 1

防止调用过程中意外解锁,导致数据不一致。

 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值