Today I Learned

A Hashrocket project

What happens on Ecto.Repo.rollback?

The rollback function interupts the execution of the function that you pass to transaction, but what is the mechanism for interupting execution?

When you call rollback you are essentially calling this code:

throw({DBConnection, conn_ref, reason})

throw is no good without a catch and you can find the try ... catch in the DBConnection module as well. It can be boiled down to this:

try do
  # call function passed to Ecto.Repo.transaction
catch
  :throw, {__MODULE__, ^conn_ref, reason} ->
    # send rollback request to database and return with {:error, reason}
    return {:error, reason}
  kind, reason ->
    # send rollback request to database and raise with reason
    :erlang.raise(kind, reason, stack)
end

This code exploits the ability of catch to both handle a throw and handle a raise.

Looking for help? At Hashrocket, we 💜 Elixir! From our many Elixir client projects, to sponsoring the Chicago Elixir Meetup, to the source code for this application, we are invested in this community. Contact us today to talk about your Elixir project.