issues with Repo.transaction + Task.async + Ecto Sandbox

455 views
Skip to first unread message

Michael Ni

unread,
Mar 13, 2017, 1:07:56 AM3/13/17
to elixir-ecto
I have a Repo.transaction,

within that I have Task.async

inside the Task.async fn, since it is a separate pid

I use 
Ecto.Adapters.SQL.Sandbox.allow(repo, parent, self())

the parent is the pid where the Repo.transaction command is


My problem is all Repo calls are timing out, I think due to the Repo.transaction blocking.




1.) If I remove the first transaction and just do Task.async,  it works, proving that Sandbox allow works

2.) if I remove the Task.async and the allows, it also works as expected,

3.) when doing this in production, it works

somehow with Repo.transaction + task.async,  + mode manual, and even shared, it is not working



Michał Muskała

unread,
Mar 13, 2017, 3:27:26 AM3/13/17
to elixi...@googlegroups.com
I think there was a bug related to this. Could you try updating to the newest db_connection? 

Michał.
--
You received this message because you are subscribed to the Google Groups "elixir-ecto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-ecto/57547d65-6779-4192-864a-4ddfd502898e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Ni

unread,
Mar 13, 2017, 6:05:56 AM3/13/17
to elixir-ecto
I am still seeing the issue with v1.1.2 and directly master from github.

I realize this may not have to do with Sandbox, but with multiple processes within a transaction

this is a simple example to explain what is going on, i kept the essentials so the syntax may not be correct

there are two tables associated with each other,  foo and bar,       foo.bar_id  (FK)   ==     bar.id (PK)

Repo.transaction(fn ->
  case Repo.insert(foo_changeset) do
    {:ok, foo} ->
       task1 = Task.async(fn ->
           bar = build_assoc(foo)
           Repo.insert(bar)
       end
  end
end)


I'm inspecting the actual query generated in the output, 
for Repo.insert(bar), the foo_id is actually correct, however when it sends the insert to the db, it can't find it and triggers rollback
i'm getting

errors: [foobar: {"does not exist", []}],


When I remove the Task.async, it works

José Valim

unread,
Mar 13, 2017, 6:10:56 AM3/13/17
to elixi...@googlegroups.com
I believe it is not about the sandbox. Transactions are per process, you cannot share a transaction across multiple process. If you have work you want to process in parallel, you can do all of the normalization on the side and leave the final step of inserting the data to the main process.



José Valim
Skype: jv.ptec
Founder and Director of R&D

Michael Ni

unread,
Mar 13, 2017, 6:20:27 AM3/13/17
to elixir-ecto, jose....@plataformatec.com.br
Thanks for clearing that up
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages