Hello!
I have some funky logic that I want to make sure I am configuring correctly. I have a fetch a lock that happens on the sales order header where writeSalesOrders is called if new lines have been inserted to the record. I follow that call with a call to a background logic that will also access that sales order. I am fetching and locking the background logic block as well to make sure there are no overlapping updates. Does that work? Or am I setting myself up for a deadlock?
haha yes Ian started that thread because of me lol. This one is a little more specific, so just making sure with the nested/background call I am not doing something wrong.
This doesn’t sound like a candidate for a deadlock. However, if everything is routed through the Sales Order header, lock timeout is definitely possible. There are always 2+ records involved in a deadlock.
Deadlock basics:
process X1 has a lock on record A and needs to lock record B
process Y1 running in parallel has a lock on record B and needs to lock record A
Deadlock basics+:
process X2 has a lock on record A and needs to lock record B
process Y2 running in parallel has a lock on record B and needs to lock record C
process Z2 running in parallel has a lock on record C and needs to lock record A
Lock timeout:
process X3 has a lock on record A and takes a really long time to do whatever it’s doing
process Y3 running in parallel needs to lock record A and gives up because it had to wait too long
@ian.p is right. You will not have a deadlock but you are definitely at risk for a lock timeout. The originating process and the background task are both trying to get a lock on the same record. If the background task is picked up before the original process ends, its Fetch And Lock action will have to wait for the original process and may time out.
You can mitigate this by leaving the “Queue Immediately” checkbox unchecked in your Queue A Background Logic Block action. This will wait until the end of the first transaction to queue WriteSalesOrders, so the lock will already be released when the background task is queued and there will be no contention.
What is the difference in functionality of calling a background LB directly with the call LB action vs using this queue back LB action? Was the best practice here?
Queue a Background Logic Block will always queue up the specified logic block to run in a separate background process. It provides the additional “Queue Immediately” checkbox that you need to specify behavior specific to queueing.
For Call A Logic Block, the difference arises based on where the calling logic block is running:
If the calling logic block is running synchronously (e.g. as part of a Field Value Changed action), the called logic block will be queued to run in the background.
If the calling logic block is running asynchronously (e.g. as a Job or part of an automatic Workflow transition) then the called logic block will run in-line, since it is already in the Background.
So my use case is kicking off from an insert to a table that happens during a workflow event. Just so I know I am understanding correctly, this falls into asynchronous functionality, correct?
It depends on whether the workflow event is synchronous or not. If it’s part of a Manual or Logic Block transition (from a synchronous logic block), then it’s synchronous. If it’s an automatic transaction, it’ll be asynchronous.