使用 Ecto/Elixir 锁定行 "FOR UPDATE OF" 具体 table
Lock row "FOR UPDATE OF" specific table using Ecto/Elixir
我想使用 FOR UPDATE OF table_name
获得一个 lock
。与FOR UPDATE
相比,FOR UPDATE OF
只锁定指定table中的行,并没有阻塞连接的行。但是,当我尝试使用以下代码片段对 Ecto 执行此操作时,它失败了。
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF calls")
原因是 Ecto 使用 calls
的别名,例如 c0
,这意味着我也必须在锁定表达式中使用别名才能使其正常工作。
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF c0")
使用别名看起来不是一个正确的方法。有没有其他方法让它工作?
从 Ecto v3
开始,无法将参数化值传递给 Query.lock
。它接受 binaries only.
[命名绑定] 也不起作用,因为 Ecto
在内部 generates aliases as it wants。
以下方法是最接近的方法,但它也不起作用,因为 Ecto.Query.lock/2
不允许插值。
使用Ecto.Query.API.fragment
,具有插值能力,关键字查询语法。有点像:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)
请注意,您现在可以使用片段插入 table 名称,请参阅 https://github.com/elixir-ecto/ecto_sql/pull/189。所以 Aleksei 的解决方案现在应该可以工作了:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)
我想使用 FOR UPDATE OF table_name
获得一个 lock
。与FOR UPDATE
相比,FOR UPDATE OF
只锁定指定table中的行,并没有阻塞连接的行。但是,当我尝试使用以下代码片段对 Ecto 执行此操作时,它失败了。
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF calls")
原因是 Ecto 使用 calls
的别名,例如 c0
,这意味着我也必须在锁定表达式中使用别名才能使其正常工作。
query =
Call
|> join_other_tables() # custom methods
|> Query.lock("FOR UPDATE OF c0")
使用别名看起来不是一个正确的方法。有没有其他方法让它工作?
从 Ecto v3
开始,无法将参数化值传递给 Query.lock
。它接受 binaries only.
[命名绑定] 也不起作用,因为 Ecto
在内部 generates aliases as it wants。
以下方法是最接近的方法,但它也不起作用,因为 Ecto.Query.lock/2
不允许插值。
使用Ecto.Query.API.fragment
,具有插值能力,关键字查询语法。有点像:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)
请注意,您现在可以使用片段插入 table 名称,请参阅 https://github.com/elixir-ecto/ecto_sql/pull/189。所以 Aleksei 的解决方案现在应该可以工作了:
from c in Call,
join: ..., # custom methods
lock: fragment("FOR UPDATE OF ?", c)