Ecto.Repo.transaction

You're seeing just the callback transaction, go back to Ecto.Repo module for more information.
Link to this callback

transaction(fun_or_multi, opts)

View Source (optional)

Specs

transaction(
  fun_or_multi :: (... -> any()) | Ecto.Multi.t(),
  opts :: Keyword.t()
) ::
  {:ok, any()}
  | {:error, any()}
  | {:error, Ecto.Multi.name(), any(), %{required(Ecto.Multi.name()) => any()}}

Runs the given function or Ecto.Multi inside a transaction.

Use with function

transaction/2 can be called with both a function of arity zero or one. The arity zero function will just be executed as is, while the arity one function will receive the repo of the transaction as its first argument, similar to Ecto.Multi.run/3.

If an unhandled error occurs the transaction will be rolled back and the error will bubble up from the transaction function. If no error occurred the transaction will be committed when the function returns. A transaction can be explicitly rolled back by calling rollback/1, this will immediately leave the function and return the value given to rollback as {:error, value}.

A successful transaction returns the value returned by the function wrapped in a tuple as {:ok, value}.

If transaction/2 is called inside another transaction, the function is simply executed, without wrapping the new transaction call in any way. If there is an error in the inner transaction and the error is rescued, or the inner transaction is rolled back, the whole outer transaction is marked as tainted, guaranteeing nothing will be committed.

Use with Ecto.Multi

Besides functions, transactions can be used with an Ecto.Multi struct. A transaction will be started, all operations applied and in case of success committed returning {:ok, changes}. In case of any errors the transaction will be rolled back and {:error, failed_operation, failed_value, changes_so_far} will be returned.

You can read more about using transactions with Ecto.Multi as well as see some examples in the Ecto.Multi documentation.

Options

See the "Shared options" section at the module documentation for more options.

Examples

import Ecto.Changeset, only: [change: 2]

MyRepo.transaction(fn ->
  MyRepo.update!(change(alice, balance: alice.balance - 10))
  MyRepo.update!(change(bob, balance: bob.balance + 10))
end)

# When passing a function of arity 1, it receives the repository itself
MyRepo.transaction(fn repo ->
  repo.insert!(%Post{})
end)

# Roll back a transaction explicitly
MyRepo.transaction(fn ->
  p = MyRepo.insert!(%Post{})
  if not Editor.post_allowed?(p) do
    MyRepo.rollback(:posting_not_allowed)
  end
end)

# With Ecto.Multi
Ecto.Multi.new()
|> Ecto.Multi.insert(:post, %Post{})
|> MyRepo.transaction