A theorethical model for eventually consolidated WebServices
I touched briefly on the data integrity issues that come with mobile scenarios on SAP ERP software, in my rant about the Apple-SAP Hype. I’ve been working as an SAP software architect for quite some years now and I’ve encountered first hand how bad SAP ERP copes with multiple client applications working on the same business objects.
Inherent flaw in SAP Software design
The SAP data model is build around record based information. When a user wants to change an object, he locks the record, makes his changes, saves the object, which updates the entire record and then releases the lock.
In the meantime, no one else can edit the object. This can become really frustrating when someone opens an object, leaves his PC, and doesn’t come back for a couple of hours.
It gets worse when a customer has created a custom transaction to interact with the same business object, but ignores the locking mechanism. Mayhem ensues. An update on the object doesn’t just change a few fields, but it updates the entire record. What is even worse, is that either user is not aware of the fact that someone else is editing the same object, and which changes were made, because the SAP system was setup as a request fulfilment system. In other words, the client requests data from the server. The server never sends data to the client on it’s own accord. (similar to webservers)
Suppose the customer now also introduces web-apps, API’s and mobile apps, with potentially even offline stores, that synchronize an hour after the facts… Universe explodes. Business users expect the data in the system, to reflect the data that the user just entered. But this isn’t the case anymore. The state of the database is no longer consolidated immediately. Due to synchronizations, offline stores and concurrent changes, the best we can offer is an eventually consolidated state. Sure, the data might not be correct now, but give it five more minutes…
Do note that these sync issues only arise in the case of updates and deletes, never for reads and creates, which is exactly why so many mobile apps only do the two latter.
This isn’t a new issue. It’s a fundamental flaw in the Software design of SAP ERP, CRM, SRM and whatnot… The only system that doesn’t suffer this flaw, is SAP BW. That’s because BW doesn’t treat an object as a record, but as a source state, with a bunch of change events, eventually consolidating in the correct state.
So, I want to apply that principle to API’s on top of SAP ERP software (beit a SOAP service, ODATA service, an RFC or an IDOC, whatever…) To do so, I came up with a theorethical model (I haven’t tested it yet in practice).
Online
So without much further ado, I bring you, someUpdateService:
The idea here is that any remote online application will first subscribe to a changeBroadCaster for the business object which it opens. (for Read, or for Edit, no matter. In fact, forget about the distinction Read/Edit. There’s only open for edit.) This changebroadcaster can be a webSocketsHandler (which also exist in modern NetWeaver ABAP stacks)
When the remote client wishes to update the businessobject, he triggers a webservice. The webservice will post the execution request to an internal queue and send back an acknowledge. The execution logic could be an RFC, which is posted to a BGRFC queue for example. The queueID would be a combination of object type and object ID (for example, BORTYPE and BORID)
Why a queue, you may ask yourself.
- SAP can decide when to process messages on a queue, depending on the system load
- if the update failes (object locked anyone?) the message remains on the queue
- multiple messages can be kept on the queue, in sequence
- queues can be automatically reprocessed
- queues can also be visualised (Business client sidepanel for pending changes anyone? With BORTYPE and BORID tags for example?)
When finally, the update message is succesfully processed from the queue, the last step in the execution logic, or a user exit on save, must post a change notifier onto the broadcaster, ideally with the fields that have changed.
All subscribed clients will then receive the changes and be able to update their UI accordingly and notify the user of the fact that things have changed (again, some eventstream in a sidepanel maybe?)
Offline
For offline applications with background sync, there’s a catch.
First of all, a background sync doesn’t have to subscribe to the data change broadcaster.
Secondly (and more important) there’s an issue with the sequence on the queue. It is possible that a synced update actually has changes that precede a change executed online on the object, which would cause an override of data entered at a later stage. That’s where we really hit the “inherent flaw in SAP ERP software design” hard.
The way to overcome that, is by applying the principles of BW to ERP. One thing we need to agree upon upfront, is that the business object in the SAP Tables must be the aggregated result of the beginstate + all changes made. Because it’s this object that will be displayed in standard transactions, and used for reads by other webservices.
Having agreed on that, we can have a closer look to the queueing mechanism and the updates. when an update on the queue has been processed succesfully, we shouldn’t just remove it from the queue. Rather, we should mark it as succesful, so that the next update can be processed, but keep it on the queue for a certain amount of time. (example, 24 hours) The queue sequence should be done based on the UTC timestamp given by the client.
If a new message arrives on the queue, we shouldn’t just reprocess that message, but also all messages that are behind it relative to the UTC timestamp.
So in the case where an update was done online at 12:30:00 and a synced update comes in from 12:15:00 afterwards, we process both the synced update from 12:15 and then the already processed update of 12:30 again. Just to make sure that we don’t override the existing data.
This only makes sense if an update doesn’t change the entire record, but rather only updates the affected fields.
To do so, it is important that the client only sends the changed fields in the update request. On SAP side, you can then inspect the metadata of the incoming request and determine which fields changed. Only these fields should then be passed to the execution logic as a parameter.
WAT
This is in other words quite a bit of work to get a reliable synchronization system. So next time your customer starts bargaining on the price of their mobile app (what, it’s just an app. Even my son builds iOS apps…), argument them that it’s not the app that matters. It’s the API and the sync framework that makes it expensive.
PS: I’ve deliberately created this as a document, so that I and others can amend it in the future once the idea has been tested and refined.
Hi Tom,
i would say it depends.....
Your idea with message based communication is not new (to SAP).
It will work for some Scenarios others like prominent example ATP will not work as it requires immediate Response.
The flaw of ERP as you Name it is for me simply a result of CRUD DB mechanism.
For sure in most web application design you have CAP design which is a contrast to the above one.
BR
Robert
hi Robert,
thanks for the input. You had me googling there for CAP. I honestly hadn't heard of that yet. Makes for an interesting read.
Message based communication is nothing new. absolutely not. just look at IDOCs as an example
but for some reason, come mobility, we suddenly all gave up on reliable messaging and sequencing and went into a fire and forget mode. (at least most of the mobile apps I've seen at customers). So I figured, time to refresh that a bit and attempt to make it manageable.
You summarized the flaw nicely. CRUD. It took me 4 paragraphs to explain the same.
If we forget about the current setup for a second, and were allowed to imagine our own database model for SAP, it would be a CR-based datamodel. No updates, no deletes. Just creation of change records.
You start off with your initial object state. Every change you want to do on that object, is actually a new record, containing only the field that changed.
A read would then take all records for the object and collapse them onto the initial state, forming the actual state.
there's also a caveat: what about a field which is actually the result of a formula on other fields? No brainer really: don't persist calculated fields, but execute the formula in your calculation view.
For any grad student, these are no brainers, but after all those years working on the SAP datamodel, many have forgotten the principals of normalization.
With S/4Hana, things are already improving, but it's still a CRUD based system.
I'm hoping that this will also change in the future.
but for now, I'm stuck on non-hana systems and have to find a way to make my customer's decentralized systems reliable. so I'm taking my best shot at a solution.
Feel free to propose improvements or counter-thoughts.
Hi Tom, i just found this on SMP and offline capabilities.
http://scn.sap.com/community/mobile/blog/2013/12/03/odata-sdk-offline--caching-data
Looks like it has also a Queue as you suggeste 🙂
Also for Delta changes there is a nice video
https://www.youtube.com/watch?v=0cAeX7mM0P8&feature=youtu.be
Hello.
I really like that you bring this to my attention
Regards,
Yogesh