Show TOC

$batch ProcessingLocate this document in the navigation structure

Use

Clients can search for and change resources exposed by a data service, in a way that each request type maps to a single HTTP request/response exchange. As these request types are based on HTTP, the usual HTTP services are also available, such as caching. In this context clients of a data service can collect or “batch up” several requests and then send that batch to the data service in a single HTTP request.

You can use $batch to collect a fixed number of operations (retrieve, create, update, delete) of an OData service in one single HTTP POST request.

Batch Request

An OData batch request is represented as a multipart MIME v1.0 message (see RFC2046 under http://www.rfc-editor.org/rfc/rfc2046.txtInformation published on non-SAP site), a standard format allowing the representation of multiple parts, each of which may have a different content type, within a single request.

Batch requests allow grouping of multiple operations (as described in OData: Operations under http://www.odata.org/documentation/operationsInformation published on non-SAP site) into a single HTTP request payload.

Batch requests are submitted as a single HTTP POST request to the $batch endpoint of a service as described in OData: URI Conventions under http://www.odata.org/documentation/uri-conventionsInformation published on non-SAP site.

The body of a batch request is made up of an ordered series of retrieve operations and/or changesets. The OData specifications define a changeset as an atomic unit of work that is made up of an unordered group of one or more of the insert, update or delete operations. The SAP Gateway framework, however, processes the changeset operations in an atomic manner and in the same order as they are defined in the changeset. Changesets cannot contain retrieve requests and cannot be nested, that is, a changeset cannot contain a changeset.

In the batch request body, each retrieve request and changeset is represented as a distinct MIME part and is separated by the boundary marker defined in the Content-Type header of the request. The contents of the MIME part which represents a changeset is itself a multipart MIME document with one part for each operation that makes up the changeset.

Each MIME part representing a retrieve request or changeset within the batch includes both Content-Type and Content-Transfer-Encoding MIME headers as seen in the examples below. The batch request boundary is the name specified in the Content-Type Header for the batch.

For more information, see http://www.odata.org/documentation/operationsInformation published on non-SAP site.

Batch Response

The batch response contains a Content-Type header specifying a content type of multipart/mixed and a batch boundary specification, which may be different from the batch boundary that was used in the corresponding request.

Within the body of the batch response is a response for each retrieve request and changeset that was in the associated batch request. The order of responses in the response body must match the order of requests in the batch request. Each response includes a Content-Type header with a value of application/http, and a Content-Transfer-Encoding MIME header with a value of binary.

A response to a retrieve request is formatted exactly as it would have appeared outside of a batch.

The body of a changeset response is either a response for all the successfully processed change request within the changeset, formatted exactly as it would have appeared outside of a batch, or a single response indicating a failure of the entire changeset.

If the set of HTTP request headers of a batch request are valid, the HTTP response status code is always 202 (Accepted). This is irrespective of whether some retrieve operations or changesets within this batch request fail or not.

As defined in the OData specification for batch processing , in case an operation within a changeset fails the batch response body contains only one single response for this changeset indicating the failure of the entire changeset.

For more information, see http://www.odata.org/documentation/operationsInformation published on non-SAP site.

Handling Operations in Batch Requests

Custom header ($batch response header) is supported for $batch requests.

Performance improvement for $batch changeset processing when the data providers is able to handle the entire operation of changeset at once at end of changeset: For this to be possible the data provider must implement the changeset handling API to process all changeset operations within one API (CHANGESET_PROCESS) and return the consolidated result of all operations to the SAP Gateway framework.

This handling is also called processing a changeset in defer mode.

When method CHANGESET_BEGIN is called a data provider can use the changing parameter CV_DEFER_MODE to inform the framework that it can process all changeset operations at once (deferred processing). Based on the list of entity set name, entity type name and action name, a data provider can dynamically set the exporting parameter mentioned above to inform the framework that it will process the current changeset at once or to reset this parameter to have a single processing as usual. Default implementation is single processing. That means without any changes in a data provider each changeset operation will be processed one after another as usual.

If CV_DEFER_MODE is set, the framework will call the data provider using the new method CHANGESET_PROCESS with importing parameter IT_CHANGESET_REQUEST containing a list of change set operations. Each entry of this list contains the technical request context IO_TECH_REQUEST_CONTEXT as usual but also a message container for error or information message happened during the processing. Response data of a change set operation including HTTP custom headers and ETag (if it exists) must be returned in changing parameter CT_CHANGESET_RESPONSE.

At the end of a changeset the framework will call method CHANHGESET_END as usual.

All retrieve operations and changesets of $batch requests are transferred at once from the SAP Gateway hub system to the backend system for processing.

All consecutive retrieve operations (until a changeset) are processed in parallel to improve performance. You can use the implementation guide (IMG) to activate or deactivate the parallelization. See also Define Parallelization of Batch Queries.

Each retrieve operation such as Read Entry or Read Feed within a $batch request will be transferred separately from the SAP Gateway hub system to the provider application in the backend system for processing.

Every changeset is treated as one Logical Unit of Work (LUW), ensuring its "all or nothing" character. All operations of a changeset will be sent at once from the SAP Gateway hub system to the provider application in the backend system for processing.

Results of all operations will be collected at the SAP Gateway hub system and sent as one HTTP response to the OData consumer.

From SAP Gateway Hub and Backend SPS09 Onwards

  • Custom header ($batch response header) is supported for $batch requests.

  • A selection of generic HTTP headers for $batch requests are available for the data provider when processing each $batch operation.

  • Performance improvement for $batch changeset processing when the data provider is able to handle the entire operation of changeset at once at end of changeset. For this to be possible, the data provider must implement the changeset handling API to process all changeset operations within one API (CHANGESET_PROCESS) and return the consolidated result of all operations to the SAP Gateway Framework.

    This handling is also called processing a changeset in defer mode.

    When method CHANGESET_BEGIN is called a data provider can use the changing parameter CV_DEFER_MODE to inform the framework that it can process all changeset operations at once (deferred processing). Based on the list of entity set name, entity type name and action name, a data provider can dynamically set the exporting parameter mentioned above to inform the framework that it will process the current changeset at once or to reset this parameter to have a single processing as usual. Default implementation is single processing. That means without any changes in a data provider each changeset operation will be processed one after another as usual.

    If CV_DEFER_MODE is set, the framework will call the data provider using the new method CHANGESET_PROCESS with importing parameter IT_CHANGESET_REQUEST containing a list of changeset operations. Each entry of this list contains the technical request context IO_TECH_REQUEST_CONTEXT as usual but also a message container for error or information message happened during the processing. Response data of a changeset operation including HTTP custom headers and ETag (if it exists) must be returned in changing parameter CT_CHANGESET_RESPONSE.

    At the end of a changeset the framework will call method CHANHGESET_END as usual.

From SAP Gateway Hub and Backend SPS 08 Onwards

From SAP Gateway hub and backend SPS 08 onwards, the $batch processing has been changed as follows to improve performance:

  • All retrieve operations and changesets of $batch requests will be transferred at once from the SAP Gateway hub system to the backend system for processing.

  • All consecutive retrieve operations (until a changeset) will be processed in parallel to improve performance. You can also use the implementation guide (IMG) to activate or deactivate the parallelization. See also Define Parallelization of Batch Queries.

Until SAP Gateway Hub or Backend of at least SPS 07

Each retrieve operation within a $batch request will be transferred separately from the SAP Gateway hub system to the provider application in the backend system for processing.

Every changeset is treated as one Logical Unit of Work (LUW), ensuring its “all or nothing” character. All operations of a changeset will be sent at once from the SAP Gateway hub system to the provider application in the backend system for processing. The operations of a changeset are processed in the same order as they are defined in this changeset.

Results of all operations will be collected at the SAP Gateway hub system and sent as one HTTP response to the OData consumer.

Additional Application API for $batch

For retrieve operations there is no special handling required. But to ensure the “all or nothing” character of a changeset there are two additional methods for changeset handling in interface /IWBEP/IF_MGW_APPL_SRV_RUNTIME:

  • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN

    All operations within a changeset must be treated as a logical unit of work. This means all or nothing. Therefore, a provider must not issue COMMIT WORK or ROLLBACK WORK during changeset processing. Otherwise, the framework will abandon the changeset processing. If the changeset contains only one operation, the check of commit or rollback is deactivated.

    At the beginning of a changeset processing, the provider will be called with this method. It can check the list of all involved entity types and actions contained in this changeset and accept the changeset handling or reject it by raising a technical exception with exception code CHANGESET_NOT_SUPPORTED. The method has a default implementation which allows only one operation per changeset in order to guarantee transactional consistency. If more than one operation is required in a changeset the implementation has to be overwritten by the application. The application then needs to ensure transactional consistency, for example not to have any commit or rollback in the chain of requests in a changeset.

    Additionally, the provider can start collecting the content of a changeset in the modifying method calls, for example update entity, and finalize it within the CHANGESET_END method call described below.

  • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END

    If the provider only updates all modifications of a changeset in internal tables, it can now update the database. A COMMIT WORK will be issued by the framework at the end of this API.

Example
Example 1 for read entity
=========================

Batch Request Header

POST  .../sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/$batch
Content-Type  multipart/mixed;boundary=batch_01869434-0001


Batch Request Body

--batch_01869434-0001
Content-Type: application/http
Content-Transfer-Encoding: binary
<at least one "carriage return line feed">

GET CarrierCollection(carrid='AA') HTTP/1.1
<at least two "carriage return line feed">

--batch_01869434-0001
Content-Type: application/http
Content-Transfer-Encoding: binary

<at least one "carriage return line feed">
GET TravelagencyCollection(agencynum='00001755') HTTP/1.1
<at least two "carriage return line feed">

--batch_01869434-0001--
 
Example for two changesets with one operation in each changeset
=================================================================

Batch Request Header

POST  .../sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/$batch
Content-Type  multipart/mixed;boundary=batch_01869434-0006


Batch Request Body

--batch_01869434-0006
Content-Type: multipart/mixed; boundary=changeset_01869434-0006-0001
<at least one "carriage return line feed">

--changeset_01869434-0006-0001
Content-Type: application/http
Content-Transfer-Encoding: binary
<at least one "carriage return line feed">


PUT TravelagencyCollection(agencynum='00001755') HTTP/1.1
Content-Type: application/atom+xml
Content-Length: 1021 (This length must be equal to or greater than the real length of the data below)
<at least one "carriage return line feed">

<update data for agencynum='00001755'>

--changeset_01869434-0006-0001--

--batch_01869434-0006
Content-Type: multipart/mixed; boundary=changeset_01869434-0006-0002
<at least one "carriage return line feed">

--changeset_01869434-0006-0002
Content-Type: application/http
Content-Transfer-Encoding: binary

PUT TravelagencyCollection(agencynum='00001756') HTTP/1.1
Content-Type: application/atom+xml
Content-Length: 1021 (This length must be equal to or greater than the real length of the data below)
<at least one "carriage return line feed">

<update data for agencynum='00001756'>

--changeset_01869434-0006-0002--

--batch_01869434-0006--


Batch Response Header

Status Code/Reason  202 (Accepted)
Content-Type  multipart/mixed; boundary=ejjeeffe0


Batch Response Body

--ejjeeffe0
Content-Type: multipart/mixed; boundary=ejjeeffe1
Content-Length:       215

--ejjeeffe1
Content-Type: application/http
Content-Length: 96
content-transfer-encoding: binary

HTTP/1.1 204 No Content
Content-Type: text/html
Content-Length: 0
dataserviceversion: 2.0


--ejjeeffe1--

--ejjeeffe0
Content-Type: multipart/mixed; boundary=ejjeeffe1
Content-Length:       215

--ejjeeffe1
Content-Type: application/http
Content-Length: 96
content-transfer-encoding: binary

HTTP/1.1 204 No Content
Content-Type: text/html
Content-Length: 0
dataserviceversion: 2.0


--ejjeeffe1--

--ejjeeffe0--

 

The batch response body of the latter example contains changeset markers because these changesets have been successfully processed.

Content ID Referencing

If you have several operations in a change set one operation can refer to another operation by using content ID referencing, rather than using the key of an entity type instance which may not be known at that time. To define a content ID for a specific operation the following syntax needs to be used in the $batch request body: Content-ID: n where n is a string selected by the application.

To define a reference to a content ID for a specific operation the following syntax needs to be used in the $batch request body: $n where n is an existing content ID that was defined for another operation from the same change set.

Content ID referencing is supported only for change sets at once (defer mode). As described above in case of “change set at once” method CHANGESET_PROCESS is called with importing parameter IT_CHANGESET_REQUEST containing a list of change set operations. The importing parameter IT_CHANGESET_REQUEST also contains information about content IDs and content ID references (fields content_id and content_id_ref).

Example

There is a specific business scenario with sales orders, and each sales order can have multiple sales order items. When creating sales orders a sales order ID is generated by the backend. When creating sales order items a sales order id needs to be provided. You want to create a change set with two operations:

  • Operation: create sales order

  • Operation: create sales order item

This demo business scenario has been implemented in demo service GWSAMPLE_BASIC and can be tested using the following URL and payload:

Sample Code
https://<host>:<port>/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/$batch
--batch_005056A5-09B1-1ED1-BF82-409B26A80300
Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80301

--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 100

POST SalesOrderSet HTTP/1.1
Content-Type: application/atom+xml
Content-Length: 1021
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:content type="application/xml">
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:SalesOrderID></d:SalesOrderID>
<d:Note>Deliver as fast as possible</d:Note>
<d:NoteLanguage>EN</d:NoteLanguage>
<d:CustomerID>0100000000</d:CustomerID>
<d:CustomerName>SAP</d:CustomerName>
<d:CurrencyCode>EUR</d:CurrencyCode>
<d:GrossAmount>25867.03</d:GrossAmount>
<d:NetAmount>21737.00</d:NetAmount>
<d:TaxAmount>4130.03</d:TaxAmount>
<d:LifecycleStatus>N</d:LifecycleStatus>
<d:LifecycleStatusDescription>New</d:LifecycleStatusDescription>
<d:BillingStatus/>
<d:BillingStatusDescription>Initial</d:BillingStatusDescription>
<d:DeliveryStatus/>
<d:DeliveryStatusDescription>Initial</d:DeliveryStatusDescription>
<d:CreatedAt>2015-03-22T23:00:00.0000000</d:CreatedAt>
<d:ChangedAt>2015-03-22T23:00:00.0000000</d:ChangedAt>
</m:properties>
</atom:content>
</atom:entry>

--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
Content-Type: application/http
Content-Transfer-Encoding: binary

POST $100/ToLineItems HTTP/1.1
Content-Type: application/atom+xml
Content-Length: 1021

<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:content type="application/xml">
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:SalesOrderID></d:SalesOrderID>
<d:ItemPosition></d:ItemPosition>
<d:ProductID>HT-1001</d:ProductID>
<d:Note>EPM DG: SO ID 0500000000 Item 0000000020</d:Note>
<d:NoteLanguage>EN</d:NoteLanguage>
<d:CurrencyCode>EUR</d:CurrencyCode><d:GrossAmount>2972.62</d:GrossAmount>
<d:NetAmount>2498.00</d:NetAmount>
<d:TaxAmount>474.62</d:TaxAmount>
<d:DeliveryDate>2015-03-29T22:00:00.0000000</d:DeliveryDate>
<d:Quantity>2</d:Quantity>
<d:QuantityUnit>EA</d:QuantityUnit>
</m:properties>
</atom:content>
</atom:entry>

--changeset_005056A5-09B1-1ED1-BF82-409B26A80301--

--batch_005056A5-09B1-1ED1-BF82-409B26A80300--
More Information

For more information on the API see the method documentation for CHANGESET_BEGIN and CHANGESET_END of /IWBEP/IF_MGW_APPL_SRV_RUNTIME.

For more information on OData operations, see http://www.odata.org/documentation/operationsInformation published on non-SAP site.

For more information on batch processing, see SAP Note 1869434 Information published on SAP site.