I'm writing an integration that requires polling Salesforce to pull down changed data. I'm worried about concurrent updates to the records that would cause me to 'miss' updates.
Service A starts updating records at 5:15:10
Service B starts updating records at 5:15:20
Service B finishes updating records at 5:15:25 (5 seconds)
Service C starts its request at 5:15:30 and requests all records modified on or after 5:15:00 (Service A's job is still running)
Service C receives a response at 5:15:35 (5 seconds)
Service A finally finishes at 5:16:00 (50 seconds)
I'd expect Service C to see all the records modified by Service B since they were committed before Service C started its request -- but none of the ones modified by Service A
I have a few choices about how I can ask for records next time I poll. I can use the highest SystemModstamp of the records returned in the first request as the 'high water mark'. Or I can return a DateTime.now() timestamp as from the server as part of the payload. But in either case, I would get a date that is higher than when Service A's transaction started -- so if SystemModstamp is the 'beginning of transaction', I'd miss all of those updates when Service C polls again
The three questions are:
Is SystemModstamp the beginning or end of the transaction?
Or, even worse, is SystemModstamp different for each record updated in a transaction?
Does anyone have a better solution out of this mess?
I clawed through all of the Salesforce docs I could find and there's not a shred of info about this.
The maximum duration of a transaction is documented to be 10 minutes so the brute force solution is to always ask for stuff that's 10 minutes older than my high water mark -- but that adds network overhead and extra client code to deal with the possible "repeats" in the stream of updates
Edit: @superfell's answer below is definitely exactly what I wanted -- but I didn't put in my initial question that my endpoints are Apex REST so I don't have access to getUpdated from Apex. I'm not going to mark that as the solution for this question.
Edit again: There is Database.getUpdated() available to Apex -- this question is answered thanks to @superfell