代码改变世界

ABAP DEQUEUE_EZTABLE 关于自定义表锁表后,锁被COMMIT和ROLLBACK自动干掉的问题

2025-07-23 17:55  覆盆子  阅读(71)  评论(0)    收藏  举报

问题:今天在使用SE11创建和使用锁表功能时,发现一个问题,就是自定义程序在锁表完成后,去调用BAPI创建物料凭证,创建完(无论成功失败)之后会做COMMIT或者ROLLBACK(FUNCTION执行),COMMIT或者ROLLBACK前自定义锁还在(SM12可查),执行后本次加的所有锁就都没了,导致自定义表数据被重复更新

锁表就用的如下FM,输入参数只有TABNAME

CALL FUNCTION 'ENQUEUE_E_TABLE'
  EXPORTING
*   MODE_RSTABLE         = 'E'
    tabname              = 'ZTABLE'
*   VARKEY               =
*   X_TABNAME            = ' '"标示参数tabname是否是十六进制的
*   X_VARKEY             = ' '"标示参数VARKEy是否是十六进制的
*   _SCOPE               = '2'
*   _WAIT                = ' '
*   _COLLECT             = ' '
  EXCEPTIONS
    foreign_lock         = 1
    system_failure       = 2
    OTHERS               = 3.

 

问题分析:

检查SE11创建的锁对象为WRITE LOCK,也没问题

经研究发现,这个问题与_SCOPE参数有关,如果不输入,则锁函数会给定默认值2,具体此参数不同值对应的解释如下

| **1** | 仅对话所有者(Dialog Owner) | 事务结束时释放(显式调用`DEQUEUE`或程序结束) | 需全程持有锁,避免因提交操作意外释放 |
| **2** | 仅更新所有者(Update Owner) | 更新任务结束时释放(需配合`CALL FUNCTION ... IN UPDATE TASK`及`COMMIT WORK`) | 标准默认值,但需确保更新任务被正确触发 |
| **3** | 对话所有者 + 更新所有者 | 两者均释放后才解锁 | 需跨对话和更新阶段的双重保护场景 |

 

如上解释,结合异常问题的情况,可知_SCOPE为默认值或者为2时,如果遇到数据更新和COMMIT WORK/ROLLBACK ,则本次加的锁会被全部释放,改成1之后,即可通过解锁FM进行释放,或者待程序执行完成后自动释放。

 

所以,_SCOPE = 1即可解决此问题