为什么在Ecto测试中获取锁定不起作用?

时间:2017-11-03 15:37:16

标签: elixir ecto

鉴于此Ecto测试:

test "fails to acquire lock" do
  %{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_lock($1)", [1337], [])
  assert lock_acquired

  %{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock($1)", [1337], [])
  refute lock_acquired
end

它不起作用。尝试pg_try_advisory_xact_lock的第二行也设法这样做。

我实际上试图这样做:

test "fails to acquire lock" do
  parent = self()
  t = Task.async(fn ->
    Ecto.Adapters.SQL.Sandbox.allow(Repo, parent, self())
    Ecto.Adapters.SQL.query!(ChargingIo.Repo, "SELECT pg_try_advisory_lock($1)", [1337], [])
    :timer.sleep(1_000)
  end)

  :timer.sleep(100)
  %{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock($1)", [1337], [])
  Task.await(t)
  refute lock_acquired
end

想要测试来自另一个进程的锁定是否设法阻止从当前进程锁定。

有趣的是,所有这些都在开发控制台中按预期工作。

欢迎提示!

1 个答案:

答案 0 :(得分:2)

好的,找到了解决方案。

setup do
  Ecto.Adapters.SQL.Sandbox.mode(Repo, :auto)
end

test "fails gracefuly when already locked" do
  t = Task.async(fn ->
    %{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_lock($1)", [1337], []) |> IO.inspect
    assert lock_acquired
    :timer.sleep(1_000)
  end)

  :timer.sleep(100)
  %{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock($1)", [1337], []) |> IO.inspect
  refute lock_acquired

  Task.await(t)
end

所以我在设置中需要:auto,如https://medium.com/@qertoip/making-sense-of-ecto-2-sql-sandbox-and-connection-ownership-modes-b45c5337c6b7中所述。