How to solve Optimistic locking failed/LOCK_COMPETITION error?
What is it and how does this happen?
A lock competition error in Zuora has many forms, you may encounter below error messages:
- "Object of class [com.zuora.zbilling.account.model.BillingAccount] with identifier [2c92c0fa6c22797e016c24cef4b6xxxx]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)”
- “[LOCK_COMPETITION] : - Operation failed due to a lock competition, please retry later.”
- “nested exception is org.hibernate.exception.LockAcquisitionException: Could not execute JDBC batch update”
The above errors indicate that there is a database lock on a given Zuora object/table because an update is still in-progress. The typical scenario is you have two competing update or create API calls that arrive for processing by the Zuora Application at or very near the same time. The first call is being executed and the second call is locked out while the first one is still in-progress.
Typical API call sequences include (but are not limited to):
Example 1: An Update call against an Account, then a Subscribe call against the same Account. Example 2: A Subscribe call against an existing Account, then an Update call against the same Account.
Example 3: Multiple Amend calls against the same Subscription, with the Amend calls sent individually instead of in a batch
Example 4: Account Bill Cycle Day update followed by another action against the same Account (Subscribe, Update, etc)
In all of the above cases, if each call is not processed serially (one-by-one), this can cause a lock competition error.
Considerations to avoid.
This is not necessarily considered a Zuora issue, but rather one of API call sequencing and timing. There are a number of approaches to limit your exposure.
Here are some options to consider:
- Review API transaction processing to ensure you aren’t overlapping competing calls. In some cases you may need to switch certain events from parallel to serial processing to eliminate overlap;
- Insert a short wait interval for select transaction sequences if subsequent updates are prone to the error;
- Insert retry logic for transactions which receive the error. Limited retry with back-off is recommended. E.g., retry after 1 second, then 2 seconds, then 4s, then 8s, then fail.
If you found my answer helpful, please give me a kudo ↑
Help others find answers faster by accepting my post as a solution √