1

Intro:

On every member registration, there is logic that creates unique number for that registration. We have solution that is using “Configuration” record, that holds formatting and counter to ensure uniqueness of that number. Since there can be a situation when this registration process will start at the same time for 2 different members, we had to ensure that this Config record is accessed only by one session at the time (no overrides or conflicts, etc). This “locking” for config is done by query with FOR UPDATE annotation. This annotation locks the record for other sessions and they are waiting until first session is finished up to 10 seconds.

Issue:

As it works good and even with few sessions running in parallel there are no big issues, when we started performance testing we found out, that if we put 10+ requests per second, it will struggle to keep up and it starts to kill some of those requests, as that 10 second waiting limit is reached for them. We have run this test for 20 minutes and almost half of them failed because of that.

Question:

How to avoid this behaviour? Is it even possible to fix this?

Notes:

  • generating list of records with pre-generated numbers is waste of storage and it may have same issue (as I’m not sure how it would behave when 2 concurrent sessions are trying to query same record)
  • this action is processed from trigger - meaning that future/queued job might not be good idea.
  • also I’m not sure if they would be ok, that this number is generated later after registration
  • Code is bulkified but since all those reg requests are handled as standalone API calls it doesn't make any difference.
6
  • Can you not use an auto-number field for this?
    – Phil W
    Jul 28, 2020 at 14:20
  • If you have to use this custom approach (I personally would switch to using an auto-number field), if this processing is all in Apex you can actually detect the timeout happening as you will get a QueryException from the SOQL execution. You could catch this and re-try. You might then be hit by limits, of course, such as CPU limit.
    – Phil W
    Jul 28, 2020 at 14:27
  • sadly, no. As there can be multiple configurations for specific situation and all of them have different prefix number. I thought of that too. In this case we need for every configuration to start counting from 0 to have biggest number range.
    – jakub
    Jul 28, 2020 at 14:27
  • For retry strategy I was thinking of that as well. Maybe in some cases it could help, but if this load would be persistent it can go into inf. loop until CPU timeout. But it might be good idea to implement that, to at least lower the chance.
    – jakub
    Jul 28, 2020 at 14:30
  • Composite index (e.g. salesforce.stackexchange.com/questions/8939/…) that includes your auto-numbered field + other fields to capture your multiple configurations
    – identigral
    Jul 28, 2020 at 17:03

1 Answer 1

0

So there was no better solution (at least for now) just to create "Tag" SObject per config using Auto Number name field as serial number sequencer. This SObjects are following strict naming convention to preserve generic backend. In apex when we are generating new record and we need serial number, we are using mapping to specific Tag SObject, which is then created dynamically, then refreshed (SOQL) and returned to generator to use that in combination with config record to build final "key".

Sadly whenever new configuration needs be added, new development work is needed( new Tag SObject and profiles/permission sets update).

Note: If you have some better idea I'm still interested in answer.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .