demo:同步接口处理接收数据
标签:
abapliumengsap接口luw |
分类: 接口相关 |
场景:
第三方调用SAP接口,创建单据,如果对方因为某种原因在极短的时间内,使用重复数据连续调用了sap接口,怎样防止重复创建单据。
之前群里聊过这个问题,我把问题抛出来,大家随便聊聊而已。
场景其实挺简单,也很常见,至于怎么实现,无非是什么加锁,加日志之类的。
我也是做了一个简单测试。
场景是推送数据到sap,创建PO。
先创建了个log表:
然后写了俩函数,分别是用锁和用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'IMPORTINGEV_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'EXPORTINGMODE_ZLMT_PO_LOG = 'X'MANDT = SY-MANDTWEB_ORDER = LS_LOG-WEB_ORDER_SCOPE = '3'EXCEPTIONSFOREIGN_LOCK = 1SYSTEM_FAILURE = 2OTHERS = 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 DAPPEND 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 bapiCALL FUNCTION 'BAPI_PO_CREATE1'EXPORTINGPOHEADER = LS_POHEADERPOHEADERX = LS_POHEADERXIMPORTINGEXPPURCHASEORDER = LV_PO_NUMBERTABLESRETURN = LT_RETURNPOITEM = LT_POITEMPOITEMX = LT_POITEMXPOCOND = LT_POCONDPOCONDX = 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'EXPORTINGWAIT = 'X'.*--------------------------------------------------------------------** 解锁*--------------------------------------------------------------------*CALL FUNCTION 'DEQUEUE_EZLMT_PO_LOG'EXPORTINGMANDT = SY-MANDTWEB_ORDER = LS_LOG-WEB_ORDER. ENDFUNCTION.
仅仅是测试代码而已。
第二个函数,只是没用锁,自己把 加锁 解锁 注释掉就行了,
(LS_LOG-WEB_ORDER
第一个函数没有重复数据。
第二个函数出现了问题:
大概就是这个意思了。
仅仅是简单测试了下,如果有什么不对的地方欢迎批评指正。谢谢!~
这个其实还有一个极端情况的问题,就是第一条锁释放后,到第一条数据落表的这个时间差里,进来的数据。
这个场景我没模拟出来。

加载中…