Sunday, December 13, 2015

Checking for Data Consistency with ADF BC REST 12.2.1

ADF BC REST supports HTTP ETag to check for data consistency. This is common approach to implement caching and optimistic locking in REST.  ADF BC REST relies on EO change indicator attribute, when change indicator attribute value is updated, new ETag is generated. All clients with previous ETag value should be prevented from updating data, without refreshing to the latest state. Read more - 22.9.1 Checking for Data Consistency When Updating ADF REST Resource Items. There are issues with data consistency check in ADF BC REST, hopefully it will be fixed in the future (read below).

To test data consistency check, enable discriminator attribute in EO. I have enabled Salary as discriminator. Each time when this attribute is changed, new ETag value will be generated and clients holding previous value will require to re-query:

GET with If-Non-Match use case (works)

Initially we don't know ETag attribute value, we can query with empty value in If-Non-Match header. Current ETag value for the row will be returned together with the data:

Copy ETag value into If-Non-Match header field and try to execute GET request. If row data is not changed (discriminator not changed), there should be no result - ETag remains the same. This can be useful when we want to check if there are any changes in the current row:

I would like to update discriminator value to check how GET would work with changed ETag. I have tried to update with PATCH from another REST client. Unfortunately current ADF BC REST implementation contains a bug and doesn't allow to update discriminator attribute (we are going to log a bug with Oracle Support):

I'm going to update discriminator value directly in DB:

Execute GET with If-Non-Match set to previous ETag - new row data will be returned (take a look, new ETag value is different from previous one):

PATCH with If-Match use case (doesn't work)

When you try to update data and row is already changed on the server (discriminator value changed), update should be prevented. This is how it should work and it almost works that way in ADF BC REST.

We can execute PATCH with If-Match value set to the same as it is set for current row on the server. Update is successful, as it should be:

Change discriminator value in the DB, this will force server to generate ETag value in the next request and it will not match with the one on the client (it should prevent next update):

Try to execute PATCH with previous ETag value, update doesn't happen (correct), but it also returns some strange message (not correct). It should be 412 (Precondition failed) HTTP code returned instead. This should be fixed (another bug to log with Oracle Support):

Download sample application - Read my previous post about ADF BC REST - Range Paging and ADF 12.2.1 ADF BC REST.

No comments: