4

I'm working on an integration between Salesforce and SAP, where Quotes are being created simultaneously in Salesforce via an API. These Quotes are associated with the same customer, let's call it Customer1. When a Quote is created, an Apex trigger checks if there is an existing Opportunity related to Customer1. If no related Opportunity is found, the trigger creates a new Opportunity.

The issue arises when two Quotes are processed concurrently:

Quote1 for Customer1 is processed, and an SOQL query is executed to check if an Opportunity exists for Customer1. Quote2 for Customer1 is processed almost simultaneously, executing the same SOQL query. Since both queries run in parallel, they both return null, indicating that no Opportunity exists for Customer1. As a result, both processes proceed to create a new Opportunity, leading to duplicate Opportunities being created for the same customer. And also creating an opportunity takes 2-3 mins.(Considiring FOR UPDATE clause realases the lock after 10 secs as said in here )

enter image description here

What I've Tried: I researched potential solutions and came across the FOR UPDATE keyword in SOQL. My understanding is that it can lock the records during a transaction to prevent other operations from modifying them until the transaction completes. However, I'm unsure if this applies to my case since the Opportunity records don't exist at the time of the query.

My Question:

How can I prevent this race condition and ensure that only one Opportunity is created for Customer1, even when multiple Quotes are processed simultaneously? Is using FOR UPDATE the correct approach here, or is there a better way to handle this scenario in Apex? Any insights or suggestions would be greatly appreciated!

Similar cases:

What are race conditions in salesforce

How do I avoid race conditions when importing a large batch and running future methods?

Salesforce transaction mutexes

7
  • As a workaround, you can utilize the capability of some unique field to prevent record duplication on the DB level if that's the main concern. Commented Aug 21 at 10:00
  • 1
    We can handle it by introducing a staging object.(This object will be more like a logging object) When simultaneous Quotes arrive, create duplicate records in the staging object. Then you can run a async process(batch if volume is large) and group together the Quotes by customer & create an Opportunity. Later, you can delete the staging object data via another async process.
    – Rohit
    Commented Aug 21 at 10:18
  • For which object are you referring to, @OlehBerehovskyi? Are you talking about Opportunities? I believe there are duplicate opportunities with the same values. Although the duplication rules provide a warning, those opportunities are still being inserted into the database Commented Aug 21 at 10:20
  • I thought about the same process, but it leads to performance issues because I already have many batches in my system. I’m hesitant to add another one @Rohit Commented Aug 21 at 10:22
  • Ok , but if the Opportunities are not needed immediately. You could have a batch executing at non-peak hours to avoid a performance hit.
    – Rohit
    Commented Aug 21 at 10:24

1 Answer 1

4

Not sure if it helps, but what if you lock the parent Account before creating the Opportunity? I guess this record is used in the transaction and you are not obliged to update it even if you set FOR UPDATE

1
  • Yeah, I see your point. Thanks for bringing that up Commented Aug 21 at 10:16

You must log in to answer this question.

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