SAP为什么要设置锁:
- 1,保持数据的一致性
如果几个用户要访问同样的资源,需要找到一种同步访问的方法去保持数据的一致性。比如说,在航班预订系统中,需要检查还有没有空座位,当检查的时候,你不想别人修改重要的数据(空座位的数量)。 - 2,仅仅用Database锁是不够的
数据库管理系统物理锁定了要修改的行记录,其他用户要等到数据库锁释放才能访问这个记录。
在SAP系统中,当一个新屏幕显示的时候会释放掉Database锁,因为屏幕的改变会触发一个隐式的DB COMMIT。如果数据是从好几个屏幕收集来的话,而且在这段时间内这些数据会分别被锁定,仅仅用Database锁就不够了。 - SAP系统在应用服务器层面有一个全局的LOCK TABLE,可以用来设置逻辑锁来锁定相关的表条目,并有ENQUEUE工作进程来管理这些锁。SAP锁是一种逻辑意义上的锁,有可能你锁定的表条目在DATABASE上根本就不存在。
创建锁对象
T-CODE:SE11,选择锁对象,并创建。
对象名称一定要以字母’E’开头,这是SAP规定,如:EZSDT_BILLING
在名称处写入需要加锁的表名,锁模式根据业务场景选择合适的模式
输入锁参数,在调用加锁函数时,就会传入对应的锁参数类型的值,加锁时只会对锁参数类型的值进行行锁定,不会影响表中其他的行。
保存并激活
程序中使用锁函数
LOCK PARAMETERS如果没有指明,系统会锁定整个表。
这里参数指明了ORDER_ID和ORDER_ITEM,系统就对等于这两个字段值的行进行加锁。
写入锁在数据修改前就要设好,避免其他用户操作时也在进行数据修改,造成两次修改不一致。
CALL FUNCTION 'ENQUEUE_EZSO_10_I' "函数名:ENQUEUE_锁对象名
EXPORTING
ORDER_ID = lv_order_id "要加锁的字段行
ORDER_ITEM = lv_order_item "要加锁的字段行
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
在修改完所有数据,就可以主动释放锁对象,如果不主动释放锁对象,程序会在以下情况隐式释放锁对象:
- 程序结束时(COMMIT或ROLL BACK时)
- 弹出MESSAGE TYPE类型为A或X的消息时
- 使用语句LEAVE PROGRAM,LEAVE TO TRANSACTION
- 在命令行输入/n回车以后
CALL FUNCTION 'DEQUEUE_EZSO_10_I' "函数名:DEQUEUE_锁对象名
EXPORTING
* MODE_ZPPT003 = 'E'
* MANDT = SY-MANDT
ORDER_ID = lv_order_id "要加锁的字段行
ORDER_ITEM = lv_order_item "要加锁的字段行
* X_FEVOR = ' '
.
锁模式补充:
-
模式E:当更改数据的时候设置为此模式。
-
模式S:本身不需要更改数据,但是希望显示的数据不被别人更改。
-
模式X:和E类似,但是不允许累加,完全独占。
如果你在一个程序里成功对一个锁对象加锁之后,如果模式为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模式的不可以。