When a record within Salesforce is being updated, the record is temporarily locked during the process. This prevents any other processes from making changes to the record while the update, and any other workflows/triggers executed as a result, are being processed. Most of the time this is not an issue, as it is fairly rare that two people in an organization will try to edit the same record at the same time. In a Salesforce community however, it is much more likely that this will happen. Most commonly, this can happen in communities that support knowledge article voting as well as community reputation scoring.
For the two above examples, Salesforce uses the child object ‘Vote’ to handle the actual information being inserted to the database, while the parent objects have a rollup field to represent the total. This way, if multiple customers on a community tried to rate a particular article at the same time, rather than only one rating being saved and the rest being locked out, multiple vote objects are created with the same parent article, each with a potentially different value.
But what if we need to allow for this kind of functionality for our own custom objects?
Let’s say we have a customer community where we want customers to be able to vote on each other’s uploaded recipes, where each recipe is stored in a custom object Recipe__c. The vote object is protected, and does not allow for the addition of custom fields or altering the types of parents it can have, so we need to implement our own object that behaves similar to vote. We can create a new custom object that has a parent lookup field to Recipe__c. This helper custom object will also have a field that contains the vote value information.
The reason this works is that using a helper object allows us to group all simultaneously initiated apex transactions from multiple sources that would normally be made directly to the record. All helper objects created within a 200ms window are grouped together and processed as a single apex transaction. This avoids a situation of multiple DML operations being called on the same record at the same time, since instead we have multiple insertions of an object that point to the same parent.
With a rollup field on the Recipe__c object to tally the vote value, we have everything we need to mimic the native vote object in Salesforce. In the next post, we will look at how we can expand on this concept to allow for complex calculations on the parent object, instead of just a value rollup.