I want to test:
- Many processes write to database in concurrent.
- Bad implementation (without transaction) results breaks data.
- Collect implementation (with transaction) results update data collectly. Not break and not lost any data.
Can I use two or more DB connecion in test?
In default Phoenix test env. Two tasks is run in serialized.
I think second task wait for first task free the connection.
defmodule EctoMysqlDemo.ConcurrentTest do
use EctoMysqlDemo.ModelCase
def select_connection_id() do
%{rows: [[connection_id]]} = Ecto.Adapters.SQL.query!(Repo, "select connection_id()")
connection_id
end
test "two concurrent transaction is serialized in test" do
start_time = System.monotonic_time(:milliseconds)
task0 = Task.async(fn->
Repo.transaction(fn->
:timer.sleep(100)
select_connection_id()
end)
end)
task1 = Task.async(fn->
Repo.transaction(fn->
:timer.sleep(100)
select_connection_id()
end)
end)
cid0 = Task.await(task0)
cid1 = Task.await(task1)
elapsed_time = System.monotonic_time(:milliseconds) - start_time
assert 200 < elapsed_time # not about 100ms
assert cid0 == cid1 # used same connection
end
end
I read Ecto.Adapters.SQL.Sandbox, I found how to use one connection in two or more processes.