加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

demo:同步接口处理接收数据

(2022-06-01 18:52:50)
标签:

abap

liumeng

sap

接口

luw

分类: 接口相关

场景:

第三方调用SAP接口,创建单据,如果对方因为某种原因在极短的时间内,使用重复数据连续调用了sap接口,怎样防止重复创建单据。


之前群里聊过这个问题,我把问题抛出来,大家随便聊聊而已。


场景其实挺简单,也很常见,至于怎么实现,无非是什么加锁,加日志之类的。


我也是做了一个简单测试。


场景是推送数据到sap,创建PO。

先创建了个log表:

demo:同步接口处理接收数据

demo:同步接口处理接收数据
然后建了个锁

demo:同步接口处理接收数据

然后写了俩函数,分别是用锁和用log表。


第一个函数




FUNCTION ZLM_CREATE_PO.*"----------------------------------------------------------------------*"*"本地接口:*"  IMPORTING*"     VALUE(IS_DATA) TYPE  ZLMT_PO_LOG OPTIONAL*"  EXPORTING*"     VALUE(ES_DATA) TYPE  ZLMT_PO_LOG*"----------------------------------------------------------------------
DATA:LT_LOG TYPE TABLE OF ZLMT_PO_LOG. DATA:LS_LOG TYPE ZLMT_PO_LOG.
DATA: LT_RETURN LIKE TABLE OF BAPIRET2, LT_POITEM LIKE TABLE OF BAPIMEPOITEM, LT_POITEMX LIKE TABLE OF BAPIMEPOITEMX, LT_POCOND LIKE TABLE OF BAPIMEPOCOND, LT_POCONDX LIKE TABLE OF BAPIMEPOCONDX, LS_POCOND LIKE BAPIMEPOCOND, LS_POCONDX LIKE BAPIMEPOCONDX. DATA: LS_POHEADER LIKE BAPIMEPOHEADER, LS_POHEADERX LIKE BAPIMEPOHEADERX, LS_RETURN LIKE BAPIRET2, LS_POITEM LIKE BAPIMEPOITEM, LS_POITEMX LIKE BAPIMEPOITEMX. DATA:LV_PO_NUMBER LIKE BAPIMEPOHEADER-PO_NUMBER.
*--------------------------------------------------------------------** 参数赋值*--------------------------------------------------------------------*
IF IS_DATA IS NOT INITIAL. MOVE-CORRESPONDING IS_DATA TO LS_LOG. ELSE.
CALL FUNCTION '/SAPSLL/GUID_CREATE' IMPORTING EV_GUID_32 = LS_LOG-GUID.
    LS_LOG-WEB_ORDER         'LM00001'  ."外部单据号 LS_LOG-BUKRS = '1710' ."公司代码 LS_LOG-BSART = 'NB' ."订单类型(采购) LS_LOG-LIFNR = 'USSU-VSF04' ."供应商或债权人的帐号 LS_LOG-EKORG = '1710' ."采购组织 LS_LOG-EKGRP = '002' ."采购组 LS_LOG-MATNR = 'MZ-RM-R300-01' ."物料编号 LS_LOG-WERKS = '1710' ."工厂 LS_LOG-LGORT = '171C' ."库存地点 LS_LOG-KSCHA = 'PMP0' ."条件类型 LS_LOG-AMOUNT = '1' ."条件金额 LS_LOG-WAERS = 'USD' ."货币码
LS_LOG-UNAME = SY-UNAME. LS_LOG-DATUM = SY-DATUM. LS_LOG-UZEIT = SY-UZEIT.
ENDIF.
*--------------------------------------------------------------------** 枷锁*--------------------------------------------------------------------*
CALL FUNCTION 'ENQUEUE_EZLMT_PO_LOG' EXPORTING MODE_ZLMT_PO_LOG = 'X' MANDT = SY-MANDT WEB_ORDER = LS_LOG-WEB_ORDER _SCOPE = '3' EXCEPTIONS FOREIGN_LOCK = 1 SYSTEM_FAILURE = 2 OTHERS = 3. IF SY-SUBRC <> 0. LS_LOG-TYPE = 'E'. LS_LOG-MESSAGE = '被锁'.
INSERT ZLMT_PO_LOG FROM LS_LOG. COMMIT WORK AND WAIT.
ES_DATA = LS_LOG. RETURN. ENDIF.
*--------------------------------------------------------------------** 检查库表内该 web order是否已经成功创建 po*--------------------------------------------------------------------* SELECT SINGLE * FROM ZLMT_PO_LOG INTO @DATA(LS_TMP) WHERE WEB_ORDER = @LS_LOG-WEB_ORDER.
IF SY-SUBRC = 0. LS_LOG-TYPE = 'E'. LS_LOG-MESSAGE = '重复创建'. INSERT ZLMT_PO_LOG FROM LS_LOG. COMMIT WORK AND WAIT.
ES_DATA = LS_LOG. RETURN. ENDIF.*--------------------------------------------------------------------** 赋值 call bapi*--------------------------------------------------------------------* CLEAR LS_POHEADER. CLEAR LS_POHEADERX. LS_POHEADER-COMP_CODE = LS_LOG-BUKRS. LS_POHEADER-CURRENCY = LS_LOG-WAERS. LS_POHEADER-DOC_DATE = SY-DATUM. LS_POHEADER-DOC_TYPE = LS_LOG-BSART. LS_POHEADER-VENDOR = LS_LOG-LIFNR. LS_POHEADER-PURCH_ORG = LS_LOG-EKORG. LS_POHEADER-PUR_GROUP = LS_LOG-EKGRP. LS_POHEADERX-COMP_CODE = 'X'. LS_POHEADERX-DOC_TYPE = 'X'. LS_POHEADERX-VENDOR = 'X'. LS_POHEADERX-PURCH_ORG = 'X'. LS_POHEADERX-PUR_GROUP = 'X'. LS_POHEADERX-CURRENCY = 'X'.  LS_POHEADERX-DOC_DATE      'X'.   CLEAR: LS_POITEM,LS_POITEMX. CLEAR: LT_POITEM[],LT_POITEMX[].
LS_POITEM-PO_ITEM = '10'. "采购凭证的项目编号 LS_POITEM-MATERIAL = LS_LOG-MATNR. "商品代码 LS_POITEM-QUANTITY = 1." "采购订单数量 LS_POITEM-PO_UNIT = 'EA' . "采购订单的计量单位 LS_POITEM-PLANT = LS_LOG-WERKS. "工厂 LS_POITEM-STGE_LOC = LS_LOG-LGORT. "库存地点
APPEND LS_POITEM TO LT_POITEM.

LS_POITEMX-PO_ITEM = '10'. "采购凭证的项目编号 LS_POITEMX-MATERIAL = 'X'. "商品代码 LS_POITEMX-QUANTITY = 'X'. "采购订单数量 LS_POITEMX-PO_UNIT = 'X' . "采购订单的计量单位 LS_POITEMX-PLANT = 'X'. "工厂 LS_POITEMX-STGE_LOC = 'X'. "库存地点

APPEND LS_POITEMX TO LT_POITEMX.
CLEAR LT_POCOND[]. CLEAR LT_POCONDX[]. CLEAR LS_POCOND.
LS_POCOND-ITM_NUMBER = '10'. LS_POCOND-COND_TYPE = LS_LOG-KSCHA. "定价条件 LS_POCOND-COND_VALUE = LS_LOG-AMOUNT. LS_POCOND-CURRENCY = LS_LOG-WAERS. "币别 LS_POCOND-CHANGE_ID = 'I'. "修改类型 I U D
APPEND LS_POCOND TO LT_POCOND.
CLEAR LS_POCONDX.
LS_POCONDX-ITM_NUMBER = '10'. LS_POCONDX-COND_TYPE = LS_LOG-AMOUNT. "定价条件 LS_POCONDX-COND_VALUE = 'X'. "价格 LS_POCONDX-CHANGE_ID = 'X'. "修改类型

IF LS_POCOND-CURRENCY IS NOT INITIAL. LS_POCONDX-CURRENCY = 'X'. "币别 ENDIF.
APPEND LS_POCONDX TO LT_POCONDX.
*& call bapi
CALL FUNCTION 'BAPI_PO_CREATE1' EXPORTING POHEADER = LS_POHEADER POHEADERX = LS_POHEADERX IMPORTING EXPPURCHASEORDER = LV_PO_NUMBER TABLES RETURN = LT_RETURN POITEM = LT_POITEM POITEMX = LT_POITEMX POCOND = LT_POCOND POCONDX = LT_POCONDX.

*--------------------------------------------------------------------** save log*--------------------------------------------------------------------* LS_LOG-EBELN = LV_PO_NUMBER. LS_LOG-TYPE = 'S'. LS_LOG-MESSAGE = '创建成功'.
LS_LOG-UNAME = SY-UNAME. LS_LOG-DATUM = SY-DATUM. LS_LOG-UZEIT = SY-UZEIT.
ES_DATA = LS_LOG.
INSERT ZLMT_PO_LOG FROM LS_LOG.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING WAIT = 'X'.
*--------------------------------------------------------------------** 解锁*--------------------------------------------------------------------* CALL FUNCTION 'DEQUEUE_EZLMT_PO_LOG' EXPORTING MANDT = SY-MANDT WEB_ORDER = LS_LOG-WEB_ORDER    .ENDFUNCTION.







仅仅是测试代码而已。

第二个函数,只是没用锁,自己把 加锁 解锁 注释掉就行了,

LS_LOG-WEB_ORDER         'LM00002')。



demo:同步接口处理接收数据

demo:同步接口处理接收数据

第一个函数没有重复数据。

第二个函数出现了问题:

demo:同步接口处理接收数据

大概就是这个意思了。

仅仅是简单测试了下,如果有什么不对的地方欢迎批评指正。谢谢!~


这个其实还有一个极端情况的问题,就是第一条锁释放后,到第一条数据落表的这个时间差里,进来的数据。

这个场景我没模拟出来。

 


 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有