为什么在 Ecto 测试中获取锁不起作用?
Why acquiring lock in Ecto tests doesn't work?
鉴于此 Ecto 测试:
test "fails to acquire lock" do
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_lock()", [1337], [])
assert lock_acquired
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock()", [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()", [1337], [])
:timer.sleep(1_000)
end)
:timer.sleep(100)
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock()", [1337], [])
Task.await(t)
refute lock_acquired
end
想测试来自另一个进程的锁定是否能够阻止当前进程的锁定。
有趣的是,所有这些在开发控制台中都按预期工作。
欢迎提出想法!
好的,找到解决方案了。
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()", [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()", [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 中所述。
鉴于此 Ecto 测试:
test "fails to acquire lock" do
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_lock()", [1337], [])
assert lock_acquired
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock()", [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()", [1337], [])
:timer.sleep(1_000)
end)
:timer.sleep(100)
%{rows: [[lock_acquired]]} = Ecto.Adapters.SQL.query!(Repo, "SELECT pg_try_advisory_xact_lock()", [1337], [])
Task.await(t)
refute lock_acquired
end
想测试来自另一个进程的锁定是否能够阻止当前进程的锁定。
有趣的是,所有这些在开发控制台中都按预期工作。
欢迎提出想法!
好的,找到解决方案了。
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()", [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()", [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 中所述。