鉴于此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
想要测试来自另一个进程的锁定是否设法阻止从当前进程锁定。
有趣的是,所有这些都在开发控制台中按预期工作。
欢迎提示!
答案 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中所述。