数据库锁是指为防止多人同时操作数据库导致数据不一致而采取的一种机制,简单来说,就是当有人加锁并且保存数据的时候,其他人就进不去或者只能浏览数据,不能修改。SAP ABAP 语言的锁是在语言层面设计的一种锁机制,它是一种逻辑锁,独立于数据库锁。
SAP 帮助 给出了一个例子:在 SAP 示例数据订票系统中,为了避免订票过度,通过 E_Booking 锁对象来对两个数据库表 SFLIGHT (航班表) 和 SBOOK (订票信息表) 进行加锁和释放。
创建锁对象
假设我们需要对数据表 spfli 添加锁,操作步骤如下:
在事务码 SE11 界面中,在 Lock object 字段输入锁对象的名称: EZ_SPFLI,然后点击 Create 按钮。用户定义的锁对象只能以 EZ 或 EY 开头。
填写描述(Short description) 以及锁的模式 (Lock mode):
锁模式 (lock mode) 有四种:
保存后激活。在激活的时候 SAP 自动生成两个 FM:
- ENQUEUE_EZ_SPFLI: 加锁
- DEQUEUE_EZ_SPFLI: 解锁
命名的规律:enqueue_ez_tablename 和 dequeue_ez_tablename。在 SE11 界面中,通过菜单 【Goto】- 【Lock modules】可以查看到 FM 名。
加锁解锁测试
ABAP 的锁是逻辑锁,某一个程序对数据表加锁后,在试图保存数据期间,该锁起作用。程序结束后,锁自动被释放。加锁期间,事务码 SM12 可以对锁对象进行查看和删除。
编写一段代码,对 spfli 表加锁,一分钟后释放:
report z_lock_spfli.
write / 'lock table spfli.'.
call function 'ENQUEUE_EZ_SPFLI'
exporting
mode_spfli = 'E'
mandt = sy-mandt
_scope = '2'
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.
else.
write / 'table spfli was locked.'.
wait up to 60 seconds.
call function 'DEQUEUE_EZ_SPFLI'
exporting
mode_spfli = 'E'
mandt = sy-mandt.
write / 'table spfli was unlocked.'.
endif.
运行期间,SM12 查看锁对象:
程序运行结束后 ,刷新 SM12 ,可以看到锁已经释放。
接下来编写一段代码测试对 SPFLI 表进行修改:
report z_save_spfli.
data: gt_spfli type standard table of spfli with header line.
select * from spfli into table gt_spfli.
modify spfli from table gt_spfli.
write / 'Data was saved successfully.'.
在程序 z_lock_spfli 运行的时候,同时运行 z_save_spfli,可以看到,锁并没有起作用,我们能够自由地对 spfli 表进行保存。这是因为 modify 语句不会自行检查是否有锁对象作用于 spfli,只有数据库层面的锁在起作用。所以,如果需要应用 ABAP 的逻辑锁,需要在保存数据库程序中调用加锁和解锁的 FM。示例代码如下:
report z_save_spfli.
data: gt_spfli type standard table of spfli with header line.
select * from spfli into table gt_spfli.
call function 'ENQUEUE_EZ_SPFLI'
exporting
mode_spfli = 'E'
mandt = sy-mandt
_scope = '2'
exceptions
foreign_lock = 1
system_failure = 2
others = 3.
if sy-subrc is initial.
modify spfli from table gt_spfli.
call function 'DEQUEUE_EZ_SPFLI'
exporting
mode_spfli = 'E'
mandt = sy-mandt.
write / 'Data was saved successfully.'.
else.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
此时,在运行加锁的时候同时运行 z_save_spfli,系统提示如下错误:
参考
Example of Lock Objects
Lock Objects in SAP ABAP - Go Coding
Table Level Lock – SAPCODES