Skip to Content
Technical Articles
Author's profile photo Sujin Appukuttan

Odata $batch processing part 1

A lot has been written on OData $batch processing. All those are knowledge enriching ones. This is an attempt to provide some more practical examples on $batch processing explicitly using json. This 2 part series, covers the basics & advanced features of $batch processing.

Topics covered are :

1) $batch wit GET, POST & PUT

2) $batch with $filter

3) Change set processing – default behavior

4) Change set processing – deferred processing

5) Comparing default vs deferred

6) Using Content-ID

Environment is :

1) Netweaver 7.4 EHP7 GWFND 740 SPS 22

2) POSTMAN Client


The Odata model taken is Material & its corresponding relation to plant

Below is the Odata model:jk

Odata modeljk

Navigation and association

Get the POSTMAN client ready




$batch Use case 1: GET request

Request body: Note that without the “Accept” the result will in xmljk

GET request

Response body:GET%20response

GET response

Detail of the result:json%20details

json details

json details

These retrieve operations within a $batch are processed using parallelization by default. The setting to enable/disable parallelization for a particular service can be done via /IWBEP/CONF_SERVICEEnable/disable%20parallelization

Enable/disable parallelization

The setting is also available from /IWFND/MAINT_SERVICE via: Service Implemenation ->click configuration


$batch Use case 2: GET with navigation (Material to plant)


GET with navigation


GET response with navigation

Detail of json result:hj

json details


$batch Use case 3: GET with $filter

Request: Retrieve materials by “Created_On” dateGET%20with%20%24filter

GET with $filter

The remaining query options are pretty much the same as usual. Let’s move to POST operation

Before we get in POST operations, its time to introduce Change set. As per SAP, $batch request is made up of ordered series of retrieve operations and/or Change sets.

1) A Change set is unordered group of one or more insert, update or delete operations. Retrieve operation is not a change set.

2) Every change set is treated as separate LUW ensuring the “ALL” or “Nothing” transaction behavior

If there are 2 Change sets with some operations within it, that implies processing of 2 LUW. When using $batch and change sets, the commit and rollback is done by the GW framework. Below are some example of change set operations.

Example: a change set containing 1 POST operationChange%20set%20example

Change set example


$batch Use case 4: Change set operation

The below $batch request contain a change set with one operation.


Change set with 1 POST operation



POST Response

The change sets internally are handled by 2 API methods :-

CHANGESET_BEGIN – by default allows only 1 operation per change set

CHANGESET_END – finalization of modification updates occurs here. The framework issue a commit work at the end of this method.


$batch Use case 5: Change set operations

Request body: Change set C01 has 2 POST operations


Change set C01


Change set C01

Response : More than one operation within a change set is not allowedaa

more than one operation not allowed

In order to have more than one operation, more than one change set is required


$batch Use case 6: Change sets with more than one operation

Below $batch request contains:

Change set C01 – 1 POST operation.

Change set C02 – 1 POST operation.

Remember each change set will treated as a separate LUW.

Request body:aa

Change set C01 POST


Change set C02 POST


Deep Insert POST responsesa

Deep insert POST response

Assuming a case where, one of the change set gets aborted, that doesn’t affect the other change set.


$batch Use case 7: 2 Change sets – one in error

Below $batch request contains two change sets. One of them is bound to fail.

Change set C01 – the LUW will be in error due to a wrong input

Change set C02 – this LUW will be success

Request body:as

Change set with wrong value in operationas

Change set with success operation


Response Change set C01 & C02

One operation is allowed per change set. That is the default behavior.

To process multiple operations within a change set, the default behavior must be changed. That is achieved using a defer mode. It’s also known as deferred processing.

How do we do that? We re-define these methods of the backend data provideraa

DPC Change set methods

So essentially we change the default behavior with defer mode

1) Set the defer mode = ‘X’ by implementing CHANGESET_BEGIN. This is an indicator that backend data provider is able to handle more than one operations at once.

2) The backend data provider will process multiple operations using a new method CHANGESET_PROCESS. All updates & modifications are collected in this method. Ensure no commit is called within the LUW to respect ALL or Nothing principle.

3) At the end of change set, CHANGESET_END method is called. The framework issues a commit work to perform the database updates here.

The defer mode processing is introduced to achieve performance by handling multiple operations within a change set.


In the next part, we shall compare time spent between a default processing and deferred processing and also look at Content-ID use case example.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Santhosh Kadiyala
      Santhosh Kadiyala

      excellent blog with great explanation

      Author's profile photo Joel Kurzon
      Joel Kurzon


      I didn't think it was excellent....I still have no idea how to use (implement) $batch in SEGW or anywhere else.

      The simple need for explaining the goal of $batch was ignored.

      Again this is a "show off" blog...totally useless in terms of education.


      Author's profile photo Rohit Aggarwal
      Rohit Aggarwal

      You should be appreciating that someone taken time to put the blog together.  If you are seeing things are missing or can be improved give the feedback in a nice way.  If you didn't understand ask questions instead of criticizing.

      Author's profile photo Igor Zhilin
      Igor Zhilin

      I feel your pain. I do think indeed this post is written by a professional <for a professional> with a lot of explaining to desire. I struggle to learn from this, too.

      Author's profile photo Joel Kurzon
      Joel Kurzon

      Sorry about this if I offended.

      Can someone point me to a blog that is written for dummy like me?


      Author's profile photo Sathish Kola
      Sathish Kola

      It's really awesome and helpful blog.
      Thank you so much

      Author's profile photo Sujin Appukuttan
      Sujin Appukuttan
      Blog Post Author

      Thank you Sathish

      Author's profile photo Somnath Paul
      Somnath Paul

      Thank you, for taking time and creating this blog post for the community.

      Just wondering, about multiple operation not allowed part. Can't it be handled through deferred mode set to true?

      In method: CHANGESET_BEGIN

      IF cv_defer_mode = abap_false.
      cv_defer_mode = abap_true.

      • Thanks, Somnath
      Author's profile photo Sujin Appukuttan
      Sujin Appukuttan
      Blog Post Author

      Yes Somnath, you can handle the deferred processing via the approach you mentioned. The same is blogged in the part 2 section.

      Author's profile photo Da Liao
      Da Liao

      It's really helpful, thank you so much!

      Author's profile photo Ruchi Dhiman
      Ruchi Dhiman

      Is this a blog for odata v4?

      Author's profile photo Shuxia - Fox Chen
      Shuxia - Fox Chen

      Thank you for the documents!

      However, I have questions for the batch on Get: in the URL, if I used $batch it shows me the 406 error that the method is not allowed, I also debug and get to know it only for post method. Then I use $metadata but looks it doesn't handle the batch request, it returns only all entity types in the service. Could you please give me some idea?

      Thanks a lot.

      Author's profile photo S. Appukuttan
      S. Appukuttan

      Irrespective of the http method "GET"  or "POST", the request URI within SAP should be /sap/opu/odata/sap/<service_name>/$batch

      The request body (--batch-- ) should contain the GET/POST request payload. For more info, do paste the URI & the request body you are trying to use





      Author's profile photo Shuxia - Fox Chen
      Shuxia - Fox Chen

      Hi Sujin,

      I found another post in, I think I get the answer.

      Thanks anyway.

      Author's profile photo Igor Zhilin
      Igor Zhilin

      Hi Sujin,

      I found out about $batch requests in the backend of Fiori apps by investigating the requests made in the web interface with F12 developer tools.

      E.g. I use $batch at https://***$batch?sap-client=100 to get the data from a CDS view in structured form

      Content-Type: application/http
      Content-Transfer-Encoding: binary
      GET ProcessDataPreview?sap-client=100&ViewName='I_SALESORDERITEM'&DraftIndicator=false HTTP/1.1
      sap-contextid-accept: header
      Accept: application/json
      Accept-Language: en
      DataServiceVersion: 2.0
      MaxDataServiceVersion: 2.0
      X-Requested-With: XMLHttpRequest
      x-csrf-token: 5v5vFUtuLZ2I7e49VpS2-g==

      Without a doubt, you are a pro in what you are doing. However, for a learner of $batch, all the basics are missing in your post, and this is very discouraging for a new learner.

      Would you kindly explain some aspects?

      • Why do we need Get X-CSRF-TOKEN in Prepare Postman? is there any guidance on this?
      • Note that without the “Accept” - what is this "Accept", where is that? It is not mentioned anywhere in your post.
      • What is the usage and meaning of $expand?
      Author's profile photo nitish chawla
      nitish chawla

      Great article. Clearly differentiates how these two(batch vs changeset) differ 🙂

      Keep Posting !!