SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息

作者:ABAP技巧与实战 约 7 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, Basis, CO, Data Engineering, FI, MM, SD, 开发, 数据工程, 物料管理, 系统管理, 财务, 销售分销

原创 无峰 [ ABAP 技巧与实战 ](javascript:void\(0\);)

**点击蓝字** 关注我们

前言

在一些自定义程序中,开发有时需要考虑多个用户同时处理同一个事务,在处理过程中对资源的占用.

**TIPS**

**SPRING**

这里说的资源是业务层面的资源含义:可以是库存数量, 库存可用量数量,信用限额或者科目预算金额等.

处理过程中临时占用资源,处理结束后,通过单据占用. 如果处理事务异常中止,则释放出占用的资源.

**为了说明清楚这个场景, 我们虚拟一个业务需求** (该业务需求曾经在某个项目上由业务提出)

业务需求说明

科目预算控制

我们需要为一些重要科目确定一个科目预算金额. 实际创建会计凭证时, 该科目的借方总额不能超过这个预算金额.

业务需求实现方案

业务需求的实现根据预算控制精确度或顾问水准,大致可以分为下面三个方案: 这三个方案各有优劣,需要按具体情况选择使用.

(方案中的读取BSEG的借方总额,如果是HANA数据库系统,可以直接用SELECT SUM 读取, 性能很好. 如果非HANA数据系统,

需要考虑优化读取方案.使用科目余额表辅助是一个优化的方式.)

_**01** _

**初级方案:**

在会计凭证增强中检查该科目在表BSEG 中的借方总额, 如果超过了配置表中预算的金额. 则报错.

这个方案中没有考虑当前凭证金额和多用户同时创建对总额的影响.

_**02** _

**中级方案**

在会计凭证增强中检查当前会计凭证中科目的借方金额+该科目在表BSEG中的总额, 如果超过了配置表中的预算的金额. 则报错

该方案考虑了当前凭证对总额的影响,但是没有考虑多个用户同时创建凭证的情况.

如果科目限额 1000 , BSEG 中已经创建了900.此时两个用户同时创建金额为60的凭证. 在中级方案中,这两个用户的凭证可能都会创建成功.最终

科目限额被超过了20. 再次创建凭证则会失败.

_**03** _

**高级方案**

在会计凭证增强中检查当前会计凭证中的科目金额+该科目在表BSEG 中的总额+其它用户正在处理的金额, 如果超过了配置表中的预算金额. 则报错.

这个方案中考虑了所有可能的情况. 理论上不会出现科目限额超出的情况.

**但是该方案有个难点就是怎么获取其它用户正在处理的金额.**

如果科目限额 1000 , BSEG 中已经创建了900.此时两个用户同时创建金额为60的凭证. 在高级方案中,这两个用户的凭证只有一个能创建成功.

获取其他用户正在处理的金额

加S类型的锁,把公司代码,科目,金额作为锁中的关键字,并用ENQUEUE_READ读取锁内容,是获取其它用户正在处理的金额的最佳方案.

_**01** _

**添加结构及锁对象**

SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图

_**02** _

**获取锁信息**

多个用户或进程,可以同时加S类型的锁.加锁信息可以在事务代码SM12中看到

SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图

_**03** _

**ENQUEUE_READ函数**

SM12中的锁信息也可以通过函数

ENQUEUE_READ读取

传入要读取的锁名称

执行后可以获取与SM12中同样的结果.

SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图

_**04** _

**解析出结果**

传出内表中的字段GARG 串赋值到 ZSHKONT_LOCK 中,可以解析出锁住的科目金额信息

高级方案的详细说明

• 读取科目预算表配置表,如果存在.继续执行增强. 否则退出增强

• 读取科目BSEG中的借方总额 ,如果已经超过了配置表中的预算额, 报错.

• 如果没有超过, 先加S锁,锁住当前凭证的金额 锁的_scope参数使用默认值2(更新成功后解锁)

• 再读取所有用户锁住的金额. 如果BSEG中的借方总额+锁金额合计>限额.报错.

• 如果没有超出. 则凭证保存成功后,系统会自动解锁.

这样就可以确保科目借方总额不会超过配置的科目预算金额.

总结

SAP锁实际是一个逻辑锁: SAP在指定的服务器中开放一个内存区域.

加锁就是在该区域中保存一条记录. 基于锁的类型, 检查该区域中是否存在相同主键的记录.

X 只要存在记录,再次加锁均失败.

E 如果存在记录,并且记录的会话ID与当前加锁的会话ID不一致,则报错. 如果不存在记录,或者会话ID一致,变更加锁次数,返回成功信息

S 不查询记录,直接写入一条新的记录.

借用SAP锁区域,读取S锁的条目并统计其中的数量或金额总额.即可完成读取其他用户占用的资源信息 .

标准可用量占用也使用了类似的逻辑(基于可用量配置确定是否启用锁占用).

锁资源是有限的,一旦锁资源用完,会导致所有需要加锁的应用报错. 实际使用时应避免大量的加锁或者找BASIS增大锁资源的参数.

** THE **

** END **

**约定**

如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.

( **如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程.

越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.** )

SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图

**公众号 : syjf1976_abap**

**ABAP开发技巧**

**微信号 : 392077**

**公众号主群加入受限, 请扫码加入副群后,向管理员申请加入主群**

SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
SAP 小技巧通过 ENQUEUE_READ 读取共享锁所著的资源信息 - 封面图
ABAP技巧与实战

关于作者:ABAP技巧与实战

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「SAP小技巧通过ENQUEUE_READ读取共享锁所著的资源信息.md」整理生成,仅用于内部技术分享与学习交流。