1

我正在使用 SAPUI5 制作工作清单应用程序。问题是,当我创建一个条目然后立即创建另一个条目时,我收到以下错误:

默认变更集实现仅允许一项操作。

我检查了$batch标题,发现有一个 MERGE 和一个 POST,MERGE 出于某种原因更新了前一个条目。任何人都可以解释一下吗?会不会是后端错误而不是 UI5 错误?

创建新条目:

_onMetadataLoaded: function() {
  var oModel = this.getView().getModel();
  var that = this;
  // ...
  oModel.read("/USERS_SET", {
    success: function(oData) {
      var oProperties = {
        Qmnum: "0",
        Otherstuff: "cool"
      };
      that._oContext = that._oView.getModel().createEntry("/ENTITYSET", {
        properties: oProperties
      });
      that.getView().setBindingContext(that._oContext);
      // ...
    }
  });
},

handleSavePress: function(oEvent) {
  // ...
  this.getView().getModel().submitChanges({
    success: function(oData) {
      // ...
    },
    error: function(oError) {
      // ...
    }
  });
},
4

2 回答 2

4

tl-dr:显然您必须使用 SAP 网关。如果您不需要在一个事务中处理这些请求,则将它们发送到不同的变更集中。如果您根本不需要批处理调用,请考虑通过在实例化时为您的模型提供 "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:首先在 try catch 块中调用 super->/iwbep/if_mgw_appl_srv_runtime~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.
    
于 2017-12-07T11:06:12.050 回答
2

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

于 2017-05-12T19:52:14.440 回答