Maxximiliann

Maxximiliann

Handling Elixir.Postgrex.Error - "could not serialize access due to read/write dependencies among transactions"

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?

Marked As Solved

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I believe you need to wrap the whole Repo.transaction in 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?

Also Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Ah. You can opt into serialized transactions on a transaction by transaction basis by doing:

Repo.transaction(fn ->
  Repo.query!("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")
  # other stuff here
end)

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

Maxximiliann

Gotcha. This did the trick:


  def delete_single_record(table_name, key, identifier) do
    try do
      Repo.transaction(fn ->
        selected_record =
          from(record in table_name,
            where: field(record, ^key) == ^identifier
          )

        Repo.delete_all(selected_record)
      end)
    catch
      Postgrex.Error -> delete_single_record(table_name, key, identifier)
    end
  end

Thanks again! :slight_smile:

Where Next?

Popular in Questions Top

New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement