diff --git a/integration_test/cases/repo.exs b/integration_test/cases/repo.exs index 68549b0c34..06aeca13ac 100644 --- a/integration_test/cases/repo.exs +++ b/integration_test/cases/repo.exs @@ -2321,6 +2321,15 @@ defmodule Ecto.Integration.RepoTest do describe "transact/2 with function" do test "return ok" do + assert :ok = + TestRepo.transact(fn -> + post1 = TestRepo.insert!(%Post{title: "1"}) + post2 = TestRepo.insert!(%Post{title: "2"}) + :ok + end) + end + + test "return ok with tuple" do assert {:ok, [post1, post2]} = TestRepo.transact(fn -> post1 = TestRepo.insert!(%Post{title: "1"}) diff --git a/lib/ecto/repo.ex b/lib/ecto/repo.ex index 6af07e8288..825e33695e 100644 --- a/lib/ecto/repo.ex +++ b/lib/ecto/repo.ex @@ -2306,9 +2306,9 @@ defmodule Ecto.Repo do end) The return value is the same as of the given `fun` which must be - `{:ok, result}` or `{:error, reason}`. + `:ok`, `{:ok, result}` or `{:error, reason}`. - If this function returns `{:ok, result}`, it means the transaction + If this function returns either `:ok`, or `{:ok, result}`, it means the transaction was successfully committed. On the other hand, if it returns `{:error, reason}`, it means the transaction was rolled back. @@ -2324,8 +2324,8 @@ defmodule Ecto.Repo do If an Elixir exception occurs the transaction will be rolled back and the exception will bubble up from the transaction function. If no exception occurs, the transaction is committed if the function - returns `{:ok, result}`. Returning `{:error, result}` will rollback the transaction - and this function will return `{:error, result}` as well. + returns either `:ok` or `{:ok, result}`. Returning `{:error, reason}` will rollback the transaction + and this function will return `{:error, reason}` as well. A transaction can be explicitly rolled back by calling `c:rollback/1`, this will immediately leave the function and return the value given to `rollback` as `{:error, value}`. @@ -2499,7 +2499,7 @@ defmodule Ecto.Repo do """ @doc group: "Transaction API" @callback transact(fun :: (-> result), opts :: Keyword.t()) :: result - when result: {:ok, any()} | {:error, any()} + when result: :ok | {:ok, any()} | {:error, any()} @callback transact(multi :: Ecto.Multi.t(), opts :: Keyword.t()) :: {:ok, map()} | Ecto.Multi.failure() diff --git a/lib/ecto/repo/transaction.ex b/lib/ecto/repo/transaction.ex index 19d89323cf..2b5d923946 100644 --- a/lib/ecto/repo/transaction.ex +++ b/lib/ecto/repo/transaction.ex @@ -9,6 +9,9 @@ defmodule Ecto.Repo.Transaction do def transact(repo, _name, fun, {adapter_meta, opts}) when is_function(fun, 1) do adapter_meta.adapter.transaction(adapter_meta, opts, fn -> case fun.(repo) do + :ok -> + :ok + {:ok, result} -> result