I have a batch Apex that processes timecards that meet a certain criteria. if the project(parent project) in the timecard has active child projects and the timecard is approved, the time in the timecard is distributed to all the child projects. Some parent projects have 100 to 800 active child projects. The batch apex processes one timecard at a time. But due to the large no .of child projects the batch hits a cpu limit when processing one timecard too. In order to get around the cpu limit error, the timecards having large no .of child projects are processed by a Queueable which chains itself in batches of 30 child projects. The batch processes timecards that have 30 or less not .of child projects. Any thing above this the queueable is initiated from the batch The queueable run in parallel to the batch and everything works well if all the parent projects in all the timecards are unique. Example: If timecard1 has parentproject1 having 100 child projects and timecard2 also has parentProject1. These two timecards will be processed by the queueable and they trip on each when time is distributed to the active child projects and cause the LOCK error mentioned above. I am assuming this happens because the queueables are executing in parallel. This does not happen to the timecards being processed by the batch apex. Can the queueables initiated from the batch be forced to execute serially? OR Is there another way to around this error?
You should use a FOR UPDATE query to make sure you have exclusive locks on the records you need to modify. Make sure you lock parents first, and then children, as appropriate. See the Locking Statements documentation for specifics. If you're concerned you won't be able to get a lock in time (you have about 5 seconds), you can query the records in a loop until you get some threshold or successfully lock the records. Time spent acquiring the locks do not count against your CPU time, although there is an ultimate 10 minute transaction limit you should also be aware of.