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.