Solved

ODATA Rest API $batch operations are not atomic.

  • 15 November 2021
  • 8 replies
  • 649 views

Userlevel 3
Badge +8

Using the ODATA Rest API we are trying to make a batch call with 2 operations in the same call.

  1. Insert a new record in the calendar exception
  2. Change task status

We have used an incorrect task status value to ensure the call fails but even though this call fails the 1st call is successful and not rolled back. The operation in the change sets should be atomic.

 

 

Request :

--batch_d3bcb804-ee77-4921-9a45-761f98d32029

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621

Content-Type: application/http

Content-Transfer-Encoding: binary

 

POST https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/person_cal_except HTTP/1.1

Content-Type: application/json

Content-ID: 3

 

{

    "person_id" : "A72033",

    "exception_type" : "DRIFT AF BIL",

    "start_dttm" : "2021-10-24T13:12:42.7997002",

    "end_dttm" : "2021-10-25T14:12:42.7997002",

    "modified_by" : "A72033",

    "created_by" : "A72033"  

}

 

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621

Content-Type: application/http

Content-Transfer-Encoding: binary

 

PATCH https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/task(83581) HTTP/1.1

Content-Type: application/json

Content-ID: 4

 

{

    "task_status": "ENROUTE123",

    "status_as_of": "2021-10-26T15:37:37.0047496",

    "user_def109": "",

    "modified_by": "A72033"

}

 

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621--

--batch_d3bcb804-ee77-4921-9a45-761f98d32029

 

 

Response :

--batchresponse_fe17b595-700c-48d5-8c9a-d5e455e71c0c

Content-Type: application/http

Content-Transfer-Encoding: binary

 

HTTP/1.1 201 Created

Location: https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/person_cal_except

Content-Type: application/json; odata.metadata=minimal

OData-Version: 4.0

 

{"@odata.context":"https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/OData/$metadata#PERSON_CAL_EXCEPT/$entity","available":"N","count_as_capacity":"N","created_by":"A72033","created_dttm":"2021-11-15T16:02:22.4889549","description":"(15) Drift af bil/IT-udstyr","end_dttm":"2021-10-25T14:12:42.7997002","exception_id":19418,"exception_type":"DRIFT AF BIL","fixed_commitment":"N","modified_by":"A72033","modified_dttm":"2021-11-15T16:02:22.5149582","person_id":"A72033","start_dttm":"2021-10-24T13:12:42.7997002"}

--batchresponse_fe17b595-700c-48d5-8c9a-d5e455e71c0c

Content-Type: application/http

Content-Transfer-Encoding: binary

 

HTTP/1.1 500 Internal Server Error

Content-Type: application/json; charset=utf-8

 

{"Message":"Invalid value of ENROUTE123 for column Task Task Status.\n\r\n"}

--batchresponse_fe17b595-700c-48d5-8c9a-d5e455e71c0c--

 

 

 

icon

Best answer by TDCSOURABH 26 November 2021, 12:33

View original

8 replies

Userlevel 7
Badge +24

Hi @TDCSOURABH,

If you were to use FSM Connect for the connection then the app param INTEGRATION_DEFAULT_EXECUTION_MODE could then control this sort of roll back behaviour. The ODATA connection will not link the two transactions as you have seen.

Are you able to clarify why you believe that this should be atomic?

Kind regards,

Lee Pinchbeck

Userlevel 3
Badge +8

Hi, 

But as per the REST API documentation, the change sets are supposed to be atomic and committed together. 

 

Regards, 

Sourabh Jain

Userlevel 7
Badge +24

Hi @TDCSOURABH,

In the line before it indicates “Batch requests are sent as sequential independent perform batch message. Within the batch, updates are grouped into changesets.

Whilst they are in a batch I am not sure these are grouped as a changeset. The two changes are not connected in anyway, one refers to the calendar exceptions and the other to a task with no mention of the person in the task update and no mention of the task in the calendar exception and nothing to indicate the connection to each other.

The example in the documentation is for parent child records which would be more like request and associated task but in your example you are using the exception calendar and the task status which do not share any relation. Do you have a parent child relation between the task table and the calendar exceptions set up in your data?

Kind regards,

Lee Pinchbeck

 

Userlevel 3
Badge +8

Hi, 

I don’t think they have to be related by data, they are only related using the change set id.  And the parent child relation is just a user story.  

I have tried with request and task , it also behaves the non atomic way,  the request change is committed even though the task change failed. 

PATCH https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/request('20190808-000105') HTTP/1.1
Content-Type: application/json
Content-ID: 3

{
    "cust_prob_descr":"test"   
}

 

PATCH https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/task(83581) HTTP/1.1
Content-Type: application/json
Content-ID: 4

{
    "task_status": "ENROUTE123",
    "status_as_of": "2021-10-26T15:37:37.0047496",
    "user_def109": "",
    "modified_by": "M41896"
}

 

 

Can you give an example request where you think the atomic behavior works. 

 

Regards, 

Sourabh Jain

 

Userlevel 7
Badge +24

What happens if you remove:

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621

Content-Type: application/http

Content-Transfer-Encoding: binary

from in between the two POST transactions?

I did not think you had to re-declare that information if it was part of the same changeset.

Userlevel 3
Badge +8

It is somehow needed, it gives the below error when  removed. 

 

--batchresponse_fffa1f58-a2a4-4c03-9983-faa142862139
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8

{"Message":"Additional text encountered after finished reading JSON content: P. Path '', line 7, position 0."}
--batchresponse_fffa1f58-a2a4-4c03-9983-faa142862139--

 

 

Request


--batch_d3bcb804-ee77-4921-9a45-761f98d32029
--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621
Content-Type: application/http
Content-Transfer-Encoding: binary

PATCH https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/request('20190808-000105') HTTP/1.1
Content-Type: application/json
Content-ID: 3

{
    "cust_prob_descr":"test"   
}

PATCH https://tsrvwapp1497.tdk.dk/IFS_T2FSM_Application/odata/task(83581) HTTP/1.1
Content-Type: application/json
Content-ID: 4

{
    "task_status": "ENROUTE123",
    "status_as_of": "2021-10-26T15:37:37.0047496",
    "user_def109": "",
    "modified_by": "M41896"
}

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621--
--batch_d3bcb804-ee77-4921-9a45-761f98d32029

 

 

 

Userlevel 7
Badge +24

Hi @TDCSOURABH,

In that case this would need to be raised to support to determine why this is not rolling back and correct.

Kind regards,

Lee Pinchbeck

Userlevel 3
Badge +8

We managed to get it to work in the atomic way. The $batch calls are atomic, there was an error on the content-type I was using (I incorrectly used the change set id in the boundary instead it should be the batch id). This is not mentioned in the ODATA documentation. 

For others who are also facing this issue, you need to include the below Content-Type in the Headers section. 

multipart/mixed;boundary=batch_d3bcb804-ee77-4921-9a45-761f98d32029

 

Sample request


--batch_d3bcb804-ee77-4921-9a45-761f98d32029
Content-Type: multipart/mixed; boundary=changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621
Content-Type: application/http
Content-Transfer-Encoding: binary

POST http://tsrvwapp1497/IFS_T2FSM_Application/OData/request HTTP/1.1
Content-Type: application/json
Content-ID: 1

{
    "modified_by":"USER1",
    "created_by":"USER1",    
    "req_type":"TEST",
    "cust_prob_descr":"Test",
    "place_id":"TEST"    
}

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621
Content-Type: application/http
Content-Transfer-Encoding: binary

POST http://tsrvwapp1497/IFS_T2FSM_Application/OData/task HTTP/1.1
Content-Type: application/json
Content-ID: 2

{
    "plan_start_dttm":"2021-10-16T16:12:42.7997002",
    "task_status":"ASSIGNED",
    "description":"Test",
    "user_def11":"7500",
    "team_id":"TEAM01",
    "created_by":"USER1",
    "plan_end_dttm":"2021-10-16T17:12:42.7997002",
    "plan_task_dur_min":"60",
    "status_as_of":"2021-10-16T16:12:42.7997002",
    "project_id":"181",
    "task_type":"TEST",    
    "person_id":"USER1",
    "status":"OP",
    "request_id":{ "@xpath_node":"//request/request_id" }
}

--changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621--
--batch_d3bcb804-ee77-4921-9a45-761f98d32029

 

 

If the 2nd call to create task fails then the 1st call to create request will automatically be rolled back.

 

 

Reply