transaction.ex (1233B)
1 defmodule Ecto.Repo.Transaction do 2 @moduledoc false 3 @dialyzer :no_opaque 4 5 def transaction(_repo, _name, fun, {adapter_meta, opts}) when is_function(fun, 0) do 6 adapter_meta.adapter.transaction(adapter_meta, opts, fun) 7 end 8 9 def transaction(repo, _name, fun, {adapter_meta, opts}) when is_function(fun, 1) do 10 adapter_meta.adapter.transaction(adapter_meta, opts, fn -> fun.(repo) end) 11 end 12 13 def transaction(repo, _name, %Ecto.Multi{} = multi, {adapter_meta, opts}) do 14 %{adapter: adapter} = adapter_meta 15 wrap = &adapter.transaction(adapter_meta, opts, &1) 16 return = &adapter.rollback(adapter_meta, &1) 17 18 case Ecto.Multi.__apply__(multi, repo, wrap, return) do 19 {:ok, values} -> {:ok, values} 20 {:error, {key, error_value, values}} -> {:error, key, error_value, values} 21 {:error, operation} -> raise "operation #{inspect operation} is manually rolling back, which is not supported by Ecto.Multi" 22 end 23 end 24 25 def in_transaction?(name) do 26 %{adapter: adapter} = meta = Ecto.Repo.Registry.lookup(name) 27 adapter.in_transaction?(meta) 28 end 29 30 def rollback(name, value) do 31 %{adapter: adapter} = meta = Ecto.Repo.Registry.lookup(name) 32 adapter.rollback(meta, value) 33 end 34 end