elixir-ecto / db_connection

Database connection behaviour

Home Page:http://hexdocs.pm/db_connection/DBConnection.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nested transaction doesn't propagate rollback value

RudolfMan opened this issue · comments

It seemed not obvious to me why transactions are flattened, but the rollback value is not. Is that on purpose?

Repo.transaction(fn -> 
  Repo.rollback(:foo)
end)
#=> {:error, :foo}

Repo.transaction(fn -> 
  Repo.transaction(fn -> 
    Repo.rollback(:foo)
  end)
end)
#=> {:error, :rollback}

Surely, currently we can check on return value of inner transaction and propagate it manually if needed, but I was expecting to see {:error, :foo} since, that was the reason of rolling back the transaction. And probably consider :rollback as default/generic reason.

In my case I have a function that in transaction calls another function that also runs in transaction.
I rely on return from transaction, either "ok" or "error" tuple with potentially my custom error reason

def foo do
  Repo.transaction(fn ->
    bar()
    # ... some other queries
  end)
end
def bar do
  Repo.transaction(fn -> 
    Repo.rollback(:bar_error)
  end)
end

And when I call foo one of the expected returns would be {:error, :bar_error}

I have put up together a naive change that propagates the rollback value if one doesn't exit.. (and also get's overriden by outer transaction's rollback, if any) RudolfMan@8827a0d

I would say both situations can be desired. For example, if I am unaware I am calling something that has a inner transaction, I would be very surprised if that affects the result of my transaction. Especially because it is a non-local return happening as a side effect. By manually cascading you at least have direct control over how this happens.