Elixir utility for retrying operations encountering Ecto’s stale entry errors (Ecto.StaleEntryError).
A more lightweight version of the retry library specifically designed to handle stale entry errors when using optimistic locking, requiring subsequent attempts.
import RetryOnStale, only: [retry_on_stale: 2]
def increase_wallet_balance(%Wallet{} = wallet, amount) do
retry_on_stale(
fn attempt ->
# refetch the latest wallet data for subsequent attempts
wallet = if attempt == 1, do: wallet, else: Repo.get!(Wallet, wallet.id)
# this function could raise a StaleEntryError
do_increase_wallet_balance(wallet, amount)
end,
max_attempts: 5, delay_ms: 100
)
end
defp do_increase_wallet_balance(%Wallet{} = wallet, amount) do
new_balance = Decimal.add(wallet.balance_amount, amount)
wallet
|> Ecto.Changeset.change(balance_amount: new_balance)
|> Ecto.Changeset.optimistic_lock(:lock_version)
|> Repo.update!()
end
GitHub repo: