SAP LDQ本地数据队列
简述
qRFC NoSend 的重新实现和重新设计,基于更高效的数据模型
LDQ 允许应用程序记录可以被接收应用程序读取的数据( pull原理)您应该确保在读取数据时它只能被调用一次,并且按照它的创建顺序( 按顺序恰好一次)。LDG 的访问遵循 FIFO 原则(先进先出 )。
如果您使用移动客户端能够在需要时从相关服务器调用数据,可以使用LDQ。
LDQ 使用队列组织不同的接收者。管理和监控基于这些队列。您可以为一个客户端创建一个或多个队列,但不同的客户端不能使用同一个队列。
LDQ 为开发人员提供了一个 API,用于允许调用者记录数据,然后由被调用的应用程序或通用解决方案(例如, 移动基础设施)的框架层读取。
API 只能在本地使用。要记录的数据以字符串( 字符或二进制)的形式传输。
由于还可以为多个客户端定义记录的数据,LDQ 确保数据只存储一次,并且在队列中对这些数据进行正确的引用。
队列彼此独立。这意味着可以基于一个队列,按照记录的顺序,只读取一次数据。各种队列之间没有隐含的数据依赖关系。
准备
删除程序 RS_LDQ_DAEMON 设计用于定期删除已处理的单元。该程序在后台异步运行。您可以使 用程序 RSLDQREORG 将此删除程序安排为后台作业。
监控
事务 SLDQMON 调用 LDQ (本地数据队列)监视器。
特点
基于后台远程函数调用 (bgRFC) 的 NoSend 场景。bgRFC NoSend场景使用链表作为队列。
基于后台远程函数调用 (bgRFC) 的NoSend场景。迄今为止,qRFC NoSend方案一直用于 MMW。
在规范阶段,构建了 LDQ 和两种替代设计理念的原型,并比较了各种数据量的读取和写入。事实证明,LDQ 选项在性能和可维护性方面都优于其他选项(参见 bgRFC NoSend MMW 性能数据)。
开发
IF_LDQ_READER 接口中的 CONFIRM_QUEUE_UNITS 方法外,LDQ类的所有方法都需要一个 Explicit Commit才能将它们的工作持久化到数据库中。此方法执行 隐式提交。
CL_LDQ_APPLICATION 类是 LDQ 读取器和 LDQ 写入器对象的工厂类。
方法 |
可见度/级别 |
描述 |
GET_WRITER |
公共静态 |
该方法创建一个 LDQ writer 对象或获取一个现有的。该方法需要本地数据队列的应用程序名称并返回接口引用。 |
GET_READER |
公共静态 |
该方法创建一个 LDQ 读取器对象或获取现有的读取器对象。该方法需要本地数据队列的应用程序名称并返回接口引用。 |
写入器类CL_LDQ_WRITER 用于初始化 LDQ 写入用例的队列表。实现接口 IF_LDQ_WRITER。
方法 |
可见度/级别 |
描述 |
SET_QUEUE_NAMES |
公共实例 |
该方法创建一个 LDQ 单元写入器对象。该方法需要一个 LDQ 队列名称表并返回一个接口引用。 |
单元写入器类CL_LDQ_UNIT_WRITER,将 LDQ 队列持久保存在数据库中。该类实现接口 IF_LDQ_UNIT_WRITER。
方法 |
可见度/级别 |
描述 |
GET_NEXT_CONTENT |
公共实例 |
创建下一个单元的内容。该方法返回一个接口引用。 |
CLASS_CONSTRUCTOR |
公共静态 |
类构造函数。 |
ON_COMMIT |
公共静态 |
将创建的 LDQ 单元持久保存在数据库中。 |
ON_ROLLBACK |
公共静态 |
回滚创建的 LDQ 单元。 |
AFTER_COMMIT |
公共静态 |
删除内部表。 |
单元内容编写器类 CL_LDQ_UNIT_CONTENT_WRITER,将有效负载写入 LDQ 单元。该类实现接口 IF_LDQ_UNIT_CONTENT_WRITER。
方法 |
可见度/级别 |
描述 |
SET_CDATA |
公共实例 |
该方法写入类似字符的数据。该方法需要一个字符串。如果单位无效,该方法将引发异常。 |
SET_XDATA |
公共实例 |
该方法写入二进制数据。该方法需要一个字节串。 |
GET_UNIT_ID |
公共实例 |
该方法读取当前的单元 ID。 |
SET_DESCRIPTION |
公共实例 |
该方法将附加描述写入单元。该方法需要一个短字符串。 |
读取器类 CL_LDQ_READER,用于初始化 LDQ 读取用例的队列表。该类实现接口 IF_LDQ_READER。
此类中的 CONFIRM_QUEUE_UNITS 方法是唯一执行 隐式提交的 LDQ 方法。此类和其他 LDQ 类的所有其他方法都需要 显式提交才能将其工作持久保存在数据库中。
方法 |
可见度/级别 |
描述 |
SET_QUEUE_NAME |
公共实例 |
该方法创建一个 LDQ 单元读取器对象。该方法需要一个 LDQ 队列名称并返回一个接口引用。当队列被另一个读取器使用时,该方法会引发异常。 |
SET_QUEUE_NAME_BY_OFFSET |
公共实例 |
为给定队列创建一个 LDQ 单元读取器对象,该队列具有给定的队列读取计数器偏移量。如果偏移量大于当前读取计数器(= 尝试跳过读取某些单元),则会引发异常。如果偏移量小于当前顶部计数器(= 尝试读取已确认的单元),则会引发异常。 |
CONFIRM_QUEUE_UNITS |
公共实例 |
标记删除已读取到给定序列号的单元。如果偏移计数器大于当前读取计数器(= 尝试确认从未读取过的单元),则会引发异常。如果偏移计数器小于当前的顶部计数器(= 尝试确认已确认的单位),则会引发异常。 注意:此方法执行 隐式提交。 |
单元读取器类 CL_LDQ_UNIT_READER,为特定 LDQ 队列提供句柄,以便读取一个或多个 LDQ 单元。该类实现接口 IF_LDQ_UNIT_READER。
方法 |
可见度/级别 |
描述 |
GET_NEXT_STATES |
公共实例 |
读取下一个单元的状态。该方法需要读取的单元数并返回单元状态表。 |
GET_NEXT_CONTENTS |
公共实例 |
读取下一个单元的内容。该方法需要读取的单元数并返回单元内容表。 |
GET_TOTAL_NUMBER_OF_UNITS |
公共实例 |
获取队列中的条目总数。 |
CONFIRM |
公共实例 |
标记删除已读取的单元。 |
CHECK_READ_SEQUENCE |
私有静态 |
验证读取单元的顺序。 |
ON_ROLLBACK |
公共静态 |
回滚称为 LDQ 单元。 |
AFTER_COMMIT |
公共静态 |
删除内部表。 |
ON_COMMIT |
公共静态 |
删除数据库中读取的 LDQ 单元。LDQ 类的所有方法都通过 Explicit Commit将其工作保存在数据库中,但 IF_LDQ_READER 接口中的 CONFIRM_QUEUE_UNITS 方法除外,该方法执行 Implicit Commit。 |
单元状态读取器类 CL_LDQ_UNIT_STATE_READER,CL_LDQ_UNIT_STATE_READER类读取一个或多个LDQ单元的状态数据,即单元大小、单元格式和单元id。该类实现接口 IF_LDQ_UNIT_STATE_READER。
方法 |
可见度/级别 |
描述 |
GET_FORMAT |
公共实例 |
该方法返回 LDQ 单元数据的格式。 |
GET_UNIT_ID |
公共实例 |
该方法返回 LDQ 单元的 Unit-ID。 |
GET_SEQUENCE_NUMBER |
公共实例 |
该方法返回一个 LDQ 单元的序列号。 |
GET_SUCCESSOR_COUNT |
公共实例 |
该方法返回队列中跟随单元的数量。 |
GET_SIZE |
公共实例 |
该方法返回 LDQ 单元数据的大小。 |
GET_DESCRIPTION |
公共实例 |
该方法返回 LDQ 单元的附加描述。 |
CHECK_COMMIT_ROLLBACK |
私有实例 |
该方法检查LDQ单元是否有效。 |
单元内容读取器类 CL_LDQ_UNIT_CONTENT_READER,CL_LDQ_UNIT_CONTENT_READER 类读取指定 LDQ 队列中一个或多个 LDQ 单元的有效负载。
方法 |
可见度/级别 |
描述 |
GET_CDATA |
公共实例 |
该方法读取类似字符的数据。该方法返回一个字符串。 |
GET_XDATA |
公共实例 |
该方法读取二进制数据。该方法返回一个字节字符串。 |
GET_FORMAT |
公共实例 |
该方法返回 LDQ 单元数据的格式。 |
GET_UNIT_ID |
公共实例 |
该方法返回 LDQ 单元的 Unit-ID。 |
GET_SEQUENCE_NUMBER |
公共实例 |
该方法返回一个 LDQ 单元的序列号。 |
GET_SUCCESSOR_COUNT |
公共实例 |
该方法返回队列中跟随单元的数量。 |
GET_DESCRIPTION |
公共实例 |
该方法返回 LDQ 单元的附加描述。 |
GET_SIZE |
公共实例 |
该方法返回 LDQ 单元数据的大小。 |
示例
LDQ写入数据示例
*a) Input parameters:
PARAMETERS: ap_name TYPE ldq_application_name DEFAULT 'Perf_TEST',qp_name TYPE ldq_queue_name DEFAULT 'LDQ_TEST_',n_queues TYPE i DEFAULT 5,n_unit TYPE i DEFAULT 100,u_size TYPE i DEFAULT 2,b_data AS CHECKBOX.*b) Variable D eclarations:
DATA: l_ldq_write TYPE REF TO if_ldq_writer,l_ldq_unit_writer TYPE REF TO if_ldq_unit_writer,l_ldq_unit_content_writer TYPE REF TO if_ldq_unit_content_writer.DATA: l_queue_name_tab TYPE ldq_queue_name_tab,l_queue_name TYPE ldq_queue_name.DATA: l_cdata TYPE string.
DATA: l_cdata2 TYPE string.DATA: l_seq_nr TYPE ldq_unit_id.
DATA: l_queue_nr(4) TYPE n.
DATA: l_size TYPE i.
DATA: l_xdata TYPE xstring.
DATA: l_times TYPE i.
DATA: l_rt_ubegin TYPE i,l_rt_uend TYPE i,l_rt_qbegin TYPE i,l_rt_qend TYPE i.*c) Creation of queue names:DO n_queues TIMES.l_queue_nr = sy-index.CONCATENATE qp_name l_queue_nr INTO l_queue_name.CONDENSE l_queue_name NO-GAPS.APPEND l_queue_name TO l_queue_name_tab.WRITE: / 'Qname: ', l_queue_name.ENDDO.ULINE.*d) Creation of binary payload:IF b_data IS NOT INITIAL.l_cdata2 = '01234'.DO 100 TIMES.CONCATENATE l_cdata2 l_cdata INTO l_cdata.ENDDO.l_xdata = l_cdata.l_size = xstrlen( l_xdata ).l_times = u_size * 1000 / l_size.CLEAR l_cdata2.DO l_times TIMES.CONCATENATE l_cdata2 l_cdata INTO l_cdata2.ENDDO.l_xdata = l_cdata2.l_size = xstrlen( l_xdata ).ELSE.IF cl_abap_char_utilities=>charsize = 1.l_cdata2 = '0123456789'.ELSE.l_cdata2 = '01234'.ENDIF.DO 100 TIMES.CONCATENATE l_cdata2 l_cdata INTO l_cdata.ENDDO.l_size = u_size - 1.DO l_size TIMES.CONCATENATE l_cdata l_cdata INTO l_cdata.ENDDO.ENDIF.*e) Creation of LDQ application object:l_ldq_write = cl_ldq_application=>get_writer( ap_name ).*f) Initialisation of the target queues for the units in this application:l_ldq_unit_writer = l_ldq_write->set_queue_names( l_queue_name_tab ).GET RUN TIME FIELD l_rt_ubegin. "aktuelle Zeit holenDO n_unit TIMES.*g) Request a unit content, i. e. status and payload of a unit, for inserting into specified queues:l_ldq_unit_content_writer = l_ldq_unit_writer->get_next_content( ).*h) Ask for sequence number of this content:
* l_seq_nr = l_ldq_unit_content_writer->get_sequence_number( ).*i) Insert the relevant data into the content:IF b_data IS INITIAL.* character payloadl_ldq_unit_content_writer->set_cdata( l_cdata ).ELSE.* binary payloadl_ldq_unit_content_writer->set_xdata( l_xdata ).ENDIF.ENDDO.*j) Persist unit contents into database:
COMMIT WORK.
监控查看数据处理状态
LDQ读取示例
*a) Input parameters:
PARAMETERS: ap_name TYPE ldq_application_name DEFAULT 'Perf_TEST',qp_name TYPE ldq_queue_name DEFAULT 'LDQ_TEST_',n_queues TYPE i DEFAULT 5,n_units TYPE i DEFAULT 10,n_times TYPE i DEFAULT 1.*b) Declarations:
DATA: l_ldq_reader TYPE REF TO if_ldq_reader,l_ldq_unit_reader TYPE REF TO if_ldq_unit_reader.
DATA: l_queue_name_tab TYPE ldq_queue_name_tab,l_queue_name TYPE ldq_queue_name.
DATA: l_xdata TYPE xstring,l_cdata TYPE string.
DATA: l_size TYPE i.
DATA: l_content_tab TYPE ldq_unit_content_reader_tab.
DATA: l_state_tab TYPE ldq_unit_state_reader_tab.
DATA: l_del TYPE i.
DATA: l_seq_nr TYPE ldq_unit_id.
DATA: l_queue_nr(4) TYPE n.
DATA: l_lines TYPE i.
DATA: l_last_lines TYPE i.
DATA: l_unit TYPE i.
DATA: l_state_wa TYPE REF TO if_ldq_unit_state_reader,l_content_wa TYPE REF TO if_ldq_unit_content_reader.DATA: l_format TYPE ldq_data_format.
DATA: l_next_state_nr TYPE i.
DATA: l_number TYPE i.TYPES: BEGIN OF lt_my_unit_reader,unit_reader TYPE REF TO if_ldq_unit_reader,queue_name TYPE ldq_queue_name,END OF lt_my_unit_reader.DATA: l_my_unit_reader_tab TYPE TABLE OF lt_my_unit_reader.
DATA: l_my_unit_reader TYPE lt_my_unit_reader.FIELD-SYMBOLS: <l_content_wa> TYPE REF TO if_ldq_unit_content_reader.
FIELD-SYMBOLS: <l_state_wa> TYPE REF TO if_ldq_unit_state_reader.*c) Creation of queue names:CLEAR: l_queue_name_tab[], l_content_tab[].DO n_queues TIMES.l_queue_nr = sy-index.CONCATENATE qp_name l_queue_nr INTO l_queue_name.CONDENSE l_queue_name NO-GAPS.APPEND l_queue_name TO l_queue_name_tab.
ENDDO.LOOP AT l_queue_name_tab INTO l_queue_name.* d) creation of ldq application object:l_ldq_reader = cl_ldq_application=>get_reader( ap_name ).* Creation of LDQ queu objects for each queue namel_my_unit_reader-unit_reader = l_ldq_reader->set_queue_name( l_queue_name ).l_my_unit_reader-queue_name = l_queue_name.APPEND l_my_unit_reader TO l_my_unit_reader_tab.ENDLOOP.** Read the block units over all queues n_times
DO n_times TIMES.LOOP AT l_my_unit_reader_tab INTO l_my_unit_reader.* e) GET n_units in one block:l_content_tab = l_my_unit_reader-unit_reader->get_next_contents( n_units ).l_unit = lines( l_content_tab ).* f) retrieve contained information out of content object:CLEAR l_number.WRITE: / l_unit, 'Qname:', l_my_unit_reader-queue_name.LOOP AT l_content_tab ASSIGNING <l_content_wa>.l_format = <l_content_wa>->get_format( ).IF l_format = 'C'.l_cdata = <l_content_wa>->get_cdata( ).ELSE.l_xdata = <l_content_wa>->get_xdata( ).ENDIF.l_seq_nr = <l_content_wa>->get_sequence_number( ).l_size = <l_content_wa>->get_size( ).l_number = l_number + 1.WRITE: /10 'number:', l_number, 'sequence number =', l_seq_nr, 'size in kb:', l_size.ENDLOOP.* g) confirm the READ unit in the database:l_my_unit_reader-unit_reader->confirm( ).* h) persist the READ status of ldq DATA into the database:COMMIT WORK.ENDLOOP.
ENDDO.
读取效果,读取完成后,在SLDQMON中可查看已被移除,如果需要读取完成后保留,需要使用方法l_ldq_reader->confirm_queue_units。
https://blog.csdn.net/xiefireworks/article/details/126326006
SAP LDQ本地数据队列相关推荐
- 网站云服务器资料本地备份,云服务器上备份本地数据
云服务器上备份本地数据 内容精选 换一换 云服务器备份(CSBS,Cloud Server Backup Service)提供对弹性云服务器(Elastic Cloud Server)和裸金属服务器( ...
- 微软投资混合连接,发布本地数据网关
在近日的一篇博文中,微软宣布正式发布本地数据网关.该网关允许创建从许多微软PaaS和SaaS服务到位于公司防火墙后面的数据源的远程连接. 在微软的文档中,该服务被称为: 一个在本地系统和微软云服务之间 ...
- SAP PI PO 管理队列 SXMS_QREG
描述 正在将 SAP Process Integration 用作应用程序系统中的中央集成服务器或本地集成引擎.异步 XI 消息的处理由 qRFC 队列中功能模块 SXMS_ASYNC_EXEC 的条 ...
- SAP携手“大数据之都” 共推大数据创新
在10月21日举办的SAP贵阳大数据峰会上,SAP与贵阳市人民政府宣布签署战略合作备忘录,共建SAP在中国的首家"SAP大数据应用创新中心".依照"立足贵阳市.服务贵州省 ...
- NNIT携手SAP完成高斯数据中心的中美跨国迁移
高斯数据中心SAP系统迁移于2017年2月14日正式完成.借助SAP LT(LT-Landscape Transformation)技术,NNIT帮助高斯国际在短短两个月的时间里,把SAP系统成功从美 ...
- sap系统前台数据与后台表之间_数据治理之SAP软件非生产数据清除方法
作者:JongWill声明:本文章仅用于SAP软件的应用与学习,不代表SAP公司.(注:文中所示截图来源SAP软件,相应著作权归SAP所有.) 我们知道SAP系统软件往往在使用多年后,底层数据库中的数 ...
- 多样化实现Windows phone 7本地数据访问5——深入Rapid Repository
上一篇多样化实现Windows Phone 7本地数据访问<4>--Rapid Repository 中初步的介绍Repid Repository作为Windows phone 7数据库 ...
- SQLServer怎样把本地数据导入到远程服务器上(转载)
平常用到mssql时间比较少,总是过一段时间就忘记应该怎么操作了.当要做mssq把本地数据导入到远程服务器的时候,就去网上搜索很久都没有图解的,所以今天自己收集一下免得下次又到处去找.希望对自己,同时 ...
- jsonStore加载远程和本地数据实例
以前一直是用jsonstore加载远程数据,最近要做combox加载webservice返回的本地数据,进了误区弄了好久,不过把store研究了下,自己做个记录方便以后使用,也给遇到同样问题的同学做个 ...
最新文章
- MySQL常见命令 [转]
- Java Web整合开发(42) -- Petstore
- alsa 测试 linux_python语音智能对话聊天机器人--linuxamp;amp;树莓派双平台兼容
- mysql bit 和 tinyint 的区别及使用场景?
- 在线实时大数据平台Storm版本兼容的问题
- C# 操作并口类,并口通信
- mysql slave 状态_python脚本 监控MySQL slave 状态
- 解决cc1plus.exe: out of memory allocating bytes
- SQL Server创建Job, 实现执行相同脚本而产生不同作业计划的探究
- android 各版本市占率,Android各版本市占率:果冻豆遥遥领先
- UI设计素材|弹窗设计技巧,快get
- RadHat 6 系列心路历程、新功能及变化
- Linux驱动学习--ALSA框架(二)声卡的创建--以SCO虚拟声卡为例
- webqq机器人java_一步一步来做WebQQ机器人-(四)(获取好友列表和群列表)
- 固态硬盘能不能提高计算机速度,固态硬盘掉速如何解决?用这几招轻松提升PC速度...
- RGB-D深度相机原理
- C++实现cmd界面简单贪吃蛇游戏
- 【MATLAB编程实例练习】-(34)直角三角形边长问题
- align-item 与 align-content 的区别
- 5款神仙插件,打工人用了效率提升5倍
热门文章
- mapmimax的学习
- 【Android -- 动画】Lottie 动画的基本使用
- 你所表现的负责可能正是在逃避责任
- 阿里云服务器Hadoop java api 上传文件报错 could only be written to 0 of the 1 minReplication nodes.
- 关于FME的Beijing54及Xian80坐标系
- 最大4k地址计算机组成原理,级计算机组成原理期末考试复习大纲资料.ppt
- 暑期2020“大咖说开源”之 孙金城:参与 ASF 开源贡献的正确姿势
- 软件工程之PERT图(概念)
- python文件去重软件_Python实现的txt文件去重功能示例
- U盘无法复制大于4G的文件