submitChanges发送两个请求

时间:2017-05-12 15:09:47

标签: odata batch-processing sapui5

我正在使用UI5制作工作清单应用程序。问题是,当我创建一个条目然后在那之后创建另一个条目时,我得到Default Changeset Implementation allows only one operation错误。我检查了$ batch标题,我看到那里有一个MERGE和一个POST,MERGE由于某种原因更新了上一个条目。任何人都能解释一下吗?它可能是后端错误而不是UI5错误吗?

创建新条目

_onMetadataLoaded: function() {
    var oModel = this._oView.getModel();
    this.resetAllCombos();
    var that = this;
    sap.ui.core.BusyIndicator.show();
    oModel.read("/USERS_SET", {
        success: function(oData) {              
            var oProperties = {
                Qmnum: "0",
                Otherstuff: "cool"
            };

            that._oContext = that._oView.getModel().createEntry("/ENTITYSET", {
                                properties: oProperties
            });

            that._oView.setBindingContext(that._oContext);

            sap.ui.core.BusyIndicator.hide();
            //update plant based dialogs
            that._setPlantDialogFilters(that, that._oView, splant);
        }
    });
},

handleSavePress: function(oEvent) {
    //prevent duplicate presses
    var oSource = oEvent.getSource();
    oSource.setEnabled(false);

    var oView = this.oView;
    var oRouter = this._oRouter;
    var oResourceBundle = this._oResourceBundle;

        if (this.checkErrors()){
            var that = this;
            sap.ui.core.BusyIndicator.show();
            oView.getModel().submitChanges({
                success: function(oData) {
                    var x = that;

                    // navigate to the new product's object view
                    var sQmnum = oView.byId("Qmnum").getValue();

                    // unbind the view to not show this object again
                    if (sQmnum !== 0 && sQmnum !== "" && that._oView.getModel().hasPendingChanges() === false){
                        oView.unbindObject();

                        // show success messge
                        var sMessage = oResourceBundle.getText("newIssueCreated", sQmnum);
                        MessageToast.show(sMessage, {
                                    closeOnBrowserNavigation: false
                        });
                        sap.ui.core.BusyIndicator.hide();

                        x.returnToMainPage();
                    }else{
                        oSource.setEnabled(true);
                        sap.ui.core.BusyIndicator.hide();
                    }
                },
                error: function(oError) {
                }
            });
        }else{
            oSource.setEnabled(true);
        }
    },
}

2 个答案:

答案 0 :(得分:1)

从错误我可以告诉你必须使用SAP GW :-)这只发生在包含多个创建/删除/更新调用的批处理请求中,并且它与事务安全相关("所有或者没有")。你要做的是重新定义相应的GW方法,我认为它是CHANGESET_BEGIN。有关详细信息,请参阅https://archive.sap.com/discussions/thread/3562720(暂时无法提供更多信息......)。

答案 1 :(得分:1)

tl-dr:显然您必须使用SAP Gateway。如果您不需要在一个事务中处理这些请求,则以不同的更改集发送它们。如果您根本不需要批量调用,请考虑通过向模型提供“useBatch”来关闭它:在实例化时为false。但是,如果您需要在一个事务中一起处理请求,那么您必须阅读以下详细信息。

为了理解这个问题,您必须了解网关以及批处理和变更集请求的工作方式。

批处理请求由捆绑在一起的多个请求组成。目的是只打开一个连接并将相关请求组合在一起,以便最大限度地减少开销。变更集在批量请求中形成较小的块,其中可以将修改请求捆绑在一起并一起处理,以确保全有或全无的特性。

所以在网关方面:假设您已经使用了SAP Gateway Service Builder(SEGW事务),那么OData服务有两个相关的类。有一个结尾... DPC和一个... DPC_EXT。不要触摸前者,当您在服务构建器中更新服务时,它将始终重新生成。后者是我们在这个例子中需要的那个。您将不得不重新定义至少两种方法:

  • / IWBEP / IF_MGW_APPL_SRV_RUNTIME〜CHANGESET_BEGIN
  • / IWBEP / IF_MGW_APPL_SRV_RUNTIME〜CHANGESET_PROCESS

默认情况下,changeset_begin方法仅允许对请求数等于1的变更集进行变更集处理。这可以自动处理,这就是存在限制的原因。如果有更多请求,则无法确保自动处理,因为它们可能彼此存在业务依赖关系。

因此,请确保在所需条件下允许对变更集进行捆绑(延迟模式)处理:

  • / IWBEP / IF_MGW_APPL_SRV_RUNTIME〜CHANGESET_BEGIN:首先调用超> / iwbep / if_mgw_appl_srv_runtime〜在try catch块changeset_begin方法,则循环在it_operation_info来决定,只有在选定的情况下缩小处理,然后允许cv_defer_mode仅对选定的案例,否则抛出/ iwbep / cx_mgw_tech_exception => changeset_not_supported异常。
  • / IWBEP / IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS:所有请求都将在it_changeset_request中可用。确保使用响应填充ct_changeset_response表。

      METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_process.
        DATA:
            lv_operation_counter TYPE i VALUE 0,
            lr_context           TYPE REF TO /iwbep/cl_mgw_request,
            lr_entry_provider    TYPE REF TO /iwbep/if_mgw_entry_provider,
            lr_message_container TYPE REF TO /iwbep/if_message_container,
            lr_entity_data       TYPE REF TO data,
            ls_context_details   TYPE /iwbep/if_mgw_core_srv_runtime=>ty_s_mgw_request_context,
            ls_changeset_response LIKE LINE OF ct_changeset_response.
    
        FIELD-SYMBOLS:
            <fs_ls_changeset_request>  LIKE LINE OF it_changeset_request.
    
        LOOP AT it_changeset_request ASSIGNING <fs_ls_changeset_request>.
            lr_context          ?= <fs_ls_changeset_request>-request_context.
            lr_entry_provider    = <fs_ls_changeset_request>-entry_provider.
            lr_message_container = <fs_ls_changeset_request>-msg_container.
            ls_context_details   = lr_context->get_request_details( ).
            CASE ls_context_details-target_entity.
              WHEN 'SomeEntity'.
                "Do the processing here
              WHEN OTHERS.
            ENDCASE.
        ENDLOOP.
      ENDMETHOD.