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

点击蓝字 关注我们

前言

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

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

添加结构及锁对象

02

获取锁信息

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

03

ENQUEUE_READ函数

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

ENQUEUE_READ读取

传入要读取的锁名称

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

04

解析出结果

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

高级方案的详细说明

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

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

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

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

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

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

总结

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

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

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

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

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

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

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

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

THE

END

约定

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

    (如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程. 越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.)

公众号 : syjf1976_abap

          ABAP开发技巧

微信号 : 392077

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值