I have a process that first reads a custom setting value to use in a numbering scheme (can't use auto-number), it +1 that value, updates it, then does a number of DML/logic code which can take a ~2-10 seconds.
The problem I have is if two users perform that process at the overlapping times, the second user doesn't read the updated value because the first update on the numbering value hasn't committed since that occurs at the end of the transaction. From what I can see in other articles, there isn't a way to force a commit (no commit, Database.updateImmediate seems only external etc). The other logical choice would be the row lock but locking stack exchange question seems to indicate it will fail after 4-5 seconds which this process could theoretically take. This would cause bigger problems than duplicated values. Is there any advice on alternative options for roughly concurrent processes to not read the same value?
If you want to simulate reproducing the issue, open up two dev consoles (use private/incognito for the second to have two sessions) and execute the code in the first, then immediately in the second window. Event though the first has called the update, it doesn't commit until after the wait loop so the second doesn't read the updated value.
Contact con = [Select Title from Contact where id='003g000000YxzQj'];
system.debug(con.Title);
con.Title += '1';
update con;
//need to commit this change now
Long startingTime = System.now().getTime();
Integer delayInMilliseconds = 1500; // One-second delay
while (System.now().getTime() - startingTime < delayInMilliseconds) {
// Do nothing until desired delay has passed
}
system.debug(con.title);