SAP锁机制(SAP Locks)经验小结

1. 数据一致性与锁

为什么要有锁机制?其背后的核心逻辑在于“保证数据的一致性”。

当数据被应用程序修改时,我们必须要保证修改后的数据具有一致性。在SAP系统中,将一致的数据状态从一个状态变动到另一个一致状态的时间跨度被称为LUW(逻辑工作单元)。

如果在LUW中发生了错误,系统将会自动撤销所有的操作,并将数据的状态回滚到初始的状态。这也就是rollback。

在SAP系统中,有两种类型的LUW,也即DB LUW和SAP LUW。

  • DB LUWs是通过database系统实现的
  • SAP LUWs是通过过特殊的SAP编程技术实现的

相应的,对应两种不同的LUW, SAP 设计了两种不同类型的锁。

  • DB Lock - 数据库系统设定加锁
  • SAP Lock - 在ABAP程序中加锁

在本文中,我将结合实际的开发经验,回顾和总结SAP Lock这个技术点。

2. SAP Locks基础概念

2.1 锁服务器

理论上讲,SAP Locks应当与SAP LUW的生命周期保持一致。

因为SAP系统可以有若干个应用服务器,为了应对不同应用服务器发送的数据请求,必须要有一个独立于应用服务器外的一个application server来处理锁的生命周期,我们通常将这个server称之为锁服务器(lock server)。

2.2 锁对象

SAP Locks的实现是基于lock object这个物理实体。通过SE11我们可以完成对于锁对象的定义。

通过锁对象,我们可以实现对于一行或多行数据的锁定,可以实现对多个数据表中数据的同时锁定(通过在定义锁对象时的外键依赖foreign key dependencies)。

当SE11定义完锁对象时,系统对自动生成一对锁函数,用于加锁和解锁。

下图展示了一个示例的锁对象:ZEGG_DOC_KEY。

有关锁对象的几点经验:

1. 锁对象中的主表,可以是一个实际上的DB表,也可以是一个结构。也就是说,SAP Lock其实是一种逻辑锁,有可能你锁定的表条目在DATABASE上根本就不存在。

2. SAP系统在应用服务器层面有一个全局的LOCK TABLE (SM12查看),用来管理逻辑锁来锁定相关的表条目,这个LOCK TABLE是cross-client的。如果,你的锁对象中,不包含MANDT这种client字段,加锁时,会对所有client上的这条数据进行锁定。

3. 如果primary table对应的structure上含有MANDT字段,在生成锁对象时,其对应的加锁函数上,会默认使用SY-MANDT值作为初始值。

4. SAP Lock支持缺省锁定,若只提供了了部分lock key,则会对缺省的key值全部锁定。举例,若lock key为 BURKS, BELNR 和GJAHR,加锁时,仅提供了 BUKRS = '1000' 其余值缺省,此时则会锁定所有 BUKRS = '1000'  的条目。同理,若加锁时,未提供任何一个lock paramter,则会锁定整个锁对象对应表。

2.3 加锁

加锁时,加锁函数会访问锁服务器的lock table,通过向lock table中写入相应条目来完成上锁动作。如果lock table中已经存在相应的锁条目而无法完成锁定,则会报出异常FOREIGN_LOCK。

下面是一个sample的加锁函数。

在使用加锁函数时,除了key字段外,还要关注几个技术参数。

2.3.1 mode_dbtab

mode_dbtab控制加锁的模式,基础模式有三种,也即E,X,S。

  • 模式E:当更改数据的时候设置为此模式。WriteLock(exclusive lock)
  • 模式X:和E类似,但是不允许累加,完全独占。Enhancedwrite lock (exclusive lock without cumulating)
  • 模式S:本身不需要更改数据,但是希望显示的数据不被别人更改。Read Lock(Shared Locked)

三种模式之间的依赖关系如下:

是否允许第二次加锁模式(同一进程内)
第一次加锁模式SEX
S允许允许不允许
E允许允许不允许
X不允许

在同一进程内,在加了S锁或E锁后,仍然可以继续加S锁或E锁。

是否允许第二次加锁模式(不同进程之间)
第一次加锁模式SEX
S允许 不允许不允许
E不允许
X不允许

在不同进程之间,在加了S后,仅可以继续加S锁。

S锁与E锁的经验小结:在仅读取数据时,加S锁,这样保证其它session中,仍然可加S锁读取数据时;在修改数据时,加E锁,这样保证修改数据时,对于数据的唯一锁定。

2.3.2 _scope

_scope参数定义了锁持续的时间,也即加锁后,何时会自动解锁。下面,我们引用SAP官方文档中的一张图,来进一步解释下这个概念。

在开始一个SAP LUW时,系统会创建两个Lock Owner(dialog owner和update owner),_scope参数用于说明这个lock归属于那个lock owner来控制。

含义
_scope = 1锁定仅属于对话所有者(dialog owner),因此仅存在于对话事务中。当调用DEQUEUE函数或事务结束时会解锁,COMMIT WORK或ROLLBACK WORK,并不会让锁失效。
_scope = 2

锁只属于更新所有者(update owner),当在更新任务CALL FUNCTION '...' IN UPDATE TASK和COMMIT WORK时,锁会被继承至此任务中。当更新事务完成时,锁会被释放。

可以使用ROLLBACK WORK,在锁被传递到更新之前释放锁。

注意:仅当调用了CALL FUNCTION '...' IN UPDATE TASK并结合COMMIT WORK时,锁才会被自动释放。仅使用COMMIT WORK并不会释放锁。

经验小结:对于_scope = 2的锁,若在程序中未调用CALL FUNCTION '...' IN UPDATE TASK任务,锁是不会自动释放的,需要手动释放锁;或创建一个dummy的IN UPDATE TASK任务,结合commit work一起使用。 例如下面的示例代码:

" ensure the locks are removed after update task

CALL FUNCTION 'ZGG_UPDATE_DUMMY' IN UPDATE TASK. 


COMMIT WORK AND WAIT.

_scope = 3该锁属于两位所有者( dialog owner 和 update owner)。换句话说,它结合了两者的行为。这个锁在两位所有者中的最后一个释放它后被取消。

2.3.3 _wait 和 _collect

_wait 和 _collect 参数一般使用的较少,其含义如下:

  • _wait :表示如果对象已经被锁定,是否等待后再尝试加锁,最大的等待时间由系统参数 ENQUE/DELAY_MAX控制。
  • _COLLECT:表示是否收集后进行统一提交。COLLECT 是一种缓存与批处理方法,即如果指定了Collect,加锁信息会放到Lock Container 中,Lock Container实际上是一个funciton Group控制的内存区域,如果程序中加了很多锁,锁信息会先放到内存中,这样可以减少对SAP锁管理系统访问。若使Lock Container中的锁生效,需执行FLUSH_ENQUEUE 这个Funciton,将锁信息更新到锁管理系统中,此时加锁操作生效,使用函数RESET_ENQUEUE可以清除Lock Container中的锁信息。

2.4 解锁

SAP锁可以通过删除锁表中的相关条目来手动释放(SM12)。

使用函数模块ENQUEUE设置SAP锁定时,传递给输入参数_SCOPE的值决定了锁定的持续时间。根据形式参数_SCOPE的值,SAP锁定可以如下释放:

加锁值锁的释放方式
_scope = 1

通过调用DEQUEUE函数释放;或等到对话程序结束时自动释放(包含的场景例如:程序自动结束、发生TYPE为A或者X的message、使用语句LEAVE PROGRAM,LEAVE TO TRANSACTION,或者在命令行输入/n回车以后)。

_scope = 2

在COMMIT WORK前通过DEQUEUE函数释放(但这没什么业务意义,因为_scope  = 2时,我们一定是希望锁持续至COMMIT WORK触发的更新任务执行完成。唯一有效的场景是,在加完_scope  = 2的锁后(COMMIT WORK执行前),程序发生了异常,此时捕获异常后,在CATCH分支需要DEQUEUE手动解锁,否则这个锁会在程序结束后,继续存在)。

通过IN UPDATE TASK任务结合commit work一起使用,在COMMIT WORK执行结束后,自动解锁。

_scope = 3

更新函数和对话程序都必须释放锁:

  • 更新释放锁对应于_SCOPE = 2
  • 对话程序中释放锁对应于_SCOPE = 1

最终锁释放由最后释放锁的动作决定。

注意:如果要使用函数模块 DEQUEUE 来在更新之外释放 SAP 锁定,那么形式参数 _SCOPE 必须被赋予一个大于或等于与函数模块 ENQUEUE 的同一形式参数传入的值。

下图是一个默认生成的dequeue函数,可以看到,dequeue时,其默认的scope是3。

2.5 上锁的一般步骤

先上锁,上锁成功之后,从数据库取数据,然后更改数据,接着更新到数据库,最后解锁。按照这个步骤,才能保证更改完全运行在锁的保护机制下。

3. 小结

本文总结了SAP Lock的工作原理,并分享了实际使用中的经验。希望本文对你有帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/659525.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

长文总结 | Python基础知识点,建议收藏

测试基础-Python篇 基础① 变量名命名规则 - 遵循PEP8原则 普通变量:max_value 全局变量:MAX_VALUE 内部变量:_local_var 和关键字重名:class_ 函数名:bar_function 类名:FooClass 布尔类型的变量名…

Matlab图像处理| 图像批量读取和存储、开闭运算

前言:因为matlab本身有很多数学公式库,图像处理有时候交给matlab会方便很多。另外,做科研就算不是专门写代码的也会了解些matlab,和做硬件的同门进行需求对接的时候往往也会要读matlab代码。所以觉得学习和自己相关matlab代码还是…

HTTPS单双向认证流程详解与联想

HTTPS单向认证 HTTPS在单向认证传输的过程中会涉及到三个密钥: 服务端的公钥和私钥,用来进行非对称加密交换密钥 客户端生成的随机密钥,用来进行对称加密传输数据 认证过程 1.客户端向服务器发起HTTPS请求,连接到服务器的443端…

margin-left: auto;使元素靠右

摘要: 今天写样式遇到一个东西,就是需要表单居右显示的,但是作用了弹性布局,其他的都不行的,一开始使用了浮动,但是使用了浮动后盒子就不继承父盒子的宽度了,移动端还行,自动回到100…

vue3 调用本地exe

1、注册表注册 在注册表中直接按照图2注册数据;也可以按照图3注册表的文件创建文档,然后点击打开,将会将注册表写入window系统。 图2 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\F1] "URL:F1 Protocol Handler" &q…

股价飙升:AI PC大变革,联想的“联想时刻”正在缔造?

按照产业的传导逻辑,在颠覆式技术到来之时,当引发这场变革的最核心技术及产品真正进入了产品化、商业化阶段,此时直触需求端的终端厂商,其成长性估算将得到市场的重新预估。 眼下AI PC之于联想就是如此。 5月27日,联…

装机数台,依旧还会心念i5-12600KF的性能和性价比优势:

近几个月的时间中, 装机差不多4台电脑,由于工作需要,计划年中再增添一台。 目前市场上英特尔CPU促销非常火爆,第12代、第13代以及第14代的产品在年中有适当的优惠。 年中也是装机的旺季,各种相关配件也相对便宜一些。…

03 Prometheus+Grafana可视化配置

03 PrometheusGrafana可视化配置 大家好,我是秋意零。接上篇Prometheus入门安装教程 grafana官网下载安装包比较慢,如果没有魔法。可关注公众号【秋意零】回复101获取 Grafana官网下载:https://grafana.com/grafana/download 这里采用的二进制…

521源码-免费源码下载-免费学习网站教程-宝塔面板ssl网站证书到期后弹出无法续期错误提示

宝塔面板如果从老版本升级到8.10后,当点站证书过期续期时会弹出错误: 排查文件是找不到问题出在哪里,导致续期错误。 解决办法:通过摸索,最简单的就是删除站点,注意:只是删除,不是把…

关于Word目录的更新

左侧标题顺序如有调整,自动目录并不会同步更新,每次都要记得在正文目录左上角点击更新目录

js监听鼠标mousemove时如何判断鼠标左键中键右键状态

首先添加鼠标移动监听 document.addEventListener(mousemove,function(e){ console.log(e.button,e.buttons,e.which); }) 1.只判断左键中键右键其中一个按键状态 e.which0;左键中键右键都没按下 e.which1;左键按下 e.which2;中键&am…

代码随想录算法训练营第四十三天 | 343. 整数拆分、96.不同的二叉搜索树

343. 整数拆分 代码随想录 视频讲解:动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分_哔哩哔哩_bilibili 解题思路 1. dp[i]对i进行拆分,得到的最大的乘积为dp[i] 2.递推公式 一个是j * (i - j) 直接相…

PS系统教学02

多个图片同时进行打开 在素材库里面选中两张图片,直接拖进PS软件中,此时会显示其中一张。当按下回车键会显示另一张。 当图层过多,需要进行选择,其中某一张图片,按住Ctrl键,进行选择点击,可以移…

集合—Map子类(HashMap、HashTable、Properties)

一、HashMap HashMap是Map接口使用频率最高的实现类。 HashMap是以键值对(key-value)形式存储数据。 key不能重复,值可以重复,允许使用null作为键或值。 添加相同的key,新的value将会覆盖原有的value。 不能保证存取顺序一样。 HashMap没有实…

Linux搭建PHP下的RabbitMQ环境(php-amqp/rabbitmq-c/erlang)

本文演示环境 Red Hat 11.2.1-9gcc (GCC) 11.2.1 20220127OpenSSL v1.1.0PHP 7.1 安装erlang erlang和RabbitMQ有版本对应关系Erlang Version Requirements,需要选择正确的版本。 本文以erlang 26和RabbitMQ 3.13.2为例。 erlang下载地址 下载包上传服务器后&a…

Pytorch-Reduction Ops

文章目录 前言1.torch.argmax()2.torch.argmin()3.torch.amax()4.torch.amin()5.torch.all()6.torch.any()7.torch.max()8.torch.dist()9.torch.logsumexp()10.torch.mean()11.torch.norm()12.torch.nansum()13.torch.prod()14.torch.cumsum()15.torch.cumprod() 前言 1.torch.…

FastGPT + OneAPI 构建知识库

云端text-embedding模型 这个在前面的文章FastGPT私有化部署OneAPI配置大模型中其实已经说过,大概就是部署完成OneAPI后,分别新建令牌和渠道,并完成FastGPT的配置。 新建渠道 选择模型的类型并配置对应的词向量模型即可,这里我…

代理注册湖北武汉投资管理公司流程和条件

我公司代理注册湖北武汉投资管理公司,现在大家都知道全国的投资管理公司已经停批了,很多需要收购的老板都是通过收购现成的投资管理公司经营的,现在我告诉大家一个好消息,我们有渠道办理湖北武汉资产管理公司,详情致电…

【Linux终端探险】:从入门到熟练,玩转基础命令的秘密(一)

文章目录 🚀Linux基础命令⭐1. 查看目录命令💥2. 切换目录👊3. 创建目录❤️4. 删除目录/文件🚲5. 修改目录/文件🌈6. 拷贝目录/文件 🚀Linux基础命令 ⭐1. 查看目录命令 在Linux中,查看目录的…

【九十七】【算法分析与设计】图论,迷宫,1207. 大臣的旅费,走出迷宫,石油采集,after与迷宫,逃离迷宫,3205. 最优配餐,路径之谜

1207. 大臣的旅费 - AcWing题库 很久以前,TT 王国空前繁荣。 为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。 为节省经费,TT 国的大臣们经过思考,制定了一套优秀的修建方案,…