Maxximiliann
Function:
def delete_single_record(table_name, key, identifier) do
Repo.transaction(fn ->
selected_record =
from(record in table_name,
where: field(record, ^key) == ^identifier
)
{num_of_deleted_records, _} = Repo.delete_all(selected_record)
case num_of_deleted_records do
0 -> Repo.delete_all(selected_record)
_ -> {:ok, num_of_deleted_records}
end
end)
end
Exception:
2021-08-27T13:10:16.977283+00:00 error: ** Task 'Elixir.Foo' terminating, ** Started from <0.2203.1>, ** When function == fun erlang:apply/2, ** arguments == [#Fun<Elixir.SomeLambda.0.42097265>,[#{error => some_message}]], ** Reason for termination == , ** {#{'__exception__' => true,'__struct__' => 'Elixir.Postgrex.Error',connection_id => nil,message => nil,postgres => #{code => serialization_failure,detail => <<"Reason code: Canceled on identification as a pivot, during commit attempt.">>,file => <<"predicate.c">>,hint => <<"The transaction might succeed if retried.">>,line => <<"4853">>,message => <<"could not serialize access due to read/write dependencies among transactions">>,pg_code => <<"40001">>,routine => <<"PreCommit_CheckForSerializationFailure">>,severity => <<"ERROR">>,unknown => <<"ERROR">>},query => nil},[{'Elixir.DBConnection',run_transaction,4,[{file,"lib/db_connection.ex"},{line,1547}]},{'Elixir.Task.Supervised',invoke_mfa,2,[{file,"lib/task/supervised.ex"},{line,90}]},{'Elixir.Task.Supervised',reply,5,[{file,"lib/task/supervised.ex"},{line,35}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}
How can this exception be handled in such a way that the deletion is simply retried rather than the system crashing?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex











Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
benwilson512
@maxximiliann you can catch the exception and try again, although you’ll likely want to place a limit on how many times you do this.
Can you elaborate a bit on what this code is supposed to do? Why does it try to do the delete again if no records were deleted?
Maxximiliann
That was my poor attempt at handling the exception, he h hehe he
New attempt:
Result:
What am I missing?
benwilson512
I believe you need to wrap the whole
Repo.transactionin a try, since the exception is occurring when the transaction commits.I am sort of surprised you are getting this error though, since this transaction isn’t (as far as I can see) using the serializable isolation level, and it’s also just a single query. Are you eliding any parts of this function?
Maxximiliann
I ran
ALTER DATABASE db_name SET DEFAULT_TRANSACTION_ISOLATION TO SERIALIZABLE;from Postgres to serialize all transactions. I wasn’t aware this could also be done straight from Elixir. Where can I read up on this?Thanks for all your help!
benwilson512
Ah. You can opt into serialized transactions on a transaction by transaction basis by doing:
For serializing all transactions setting the default as you’ve done is probably easiest.
Back to your original issue, calling delete_all twice in the same transaction isn’t going to help, you need to retry the whole transaction. Merely attempting it one more time may not be enough either, it may take several tries. I would reconsider whether you want this default.
Maxximiliann
Gotcha. This did the trick:
Thanks again!