Elixir 如何将诸如after_commit回调之类的东西附加到一个Ecto事务?
有没有一种方法可以将回调附加到提交事务后调用的Ecto事务?我在找类似的东西 我正在处理的用例是在执行操作后引发副作用。例如,在下面的代码中,我想在Elixir 如何将诸如after_commit回调之类的东西附加到一个Ecto事务?,elixir,ecto,Elixir,Ecto,有没有一种方法可以将回调附加到提交事务后调用的Ecto事务?我在找类似的东西 我正在处理的用例是在执行操作后引发副作用。例如,在下面的代码中,我想在App.ServiceB.run/0中启动副作用,但由于它是在调用方启动的事务上下文中被调用的,因此我不能保证操作不会回滚 defmodule App.ServiceA do alias App.Repo def run() do App.Repo.transaction(fn -> with {:ok, _} &
App.ServiceB.run/0
中启动副作用,但由于它是在调用方启动的事务上下文中被调用的,因此我不能保证操作不会回滚
defmodule App.ServiceA do
alias App.Repo
def run() do
App.Repo.transaction(fn ->
with {:ok, _} <- ServiceB.run(),
{:ok, entity} <- {:error, :foo}
do
{:ok, entity}
else
{:error, reason} -> Repo.rollback(reason)
end
end)
end
end
defmodule App.ServiceB do
def run() do
with {:ok, entity} <- Repo.insert(create_changeset()) do
# initiate side effects
{:ok, entity}
end
end
defp create_changeset() do
# ...
end
end
defmodule App.ServiceA do
别名App.Repo
def run()do
应用回购交易(fn->
使用{:ok,{p}时,在Ecto中没有后提交挂钩。但是事务调用返回{:ok,result}
或{:error,message}
,因此您可以按如下方式匹配返回值:
def run() do
with {:ok, result} <- App.Repo.transaction(fn ->
with {:ok, _} <- ServiceB.run(),
{:ok, entity} <- {:error, :foo} do
{:ok, entity}
else
{:error, reason} -> Repo.rollback(reason)
end
end) do
# after commit (only if it succeeded)
end
end
def run()do
使用{:确定,结果}
使用{:ok,{p}时,在Ecto中没有后提交挂钩。但是事务调用返回{:ok,result}
或{:error,message}
,因此您可以按如下方式匹配返回值:
def run() do
with {:ok, result} <- App.Repo.transaction(fn ->
with {:ok, _} <- ServiceB.run(),
{:ok, entity} <- {:error, :foo} do
{:ok, entity}
else
{:error, reason} -> Repo.rollback(reason)
end
end) do
# after commit (only if it succeeded)
end
end
def run()do
使用{:确定,结果}
对于{:好的,{同样@smallbutton com的答案是绝对正确的,我们通常用于此类任务。它比裸事务更健壮,因为它在启动事务之前检查变更集,等等
对于您的用例,代码看起来有点
defmodule多个服务都有
别名EXTO.Multi
def运行(foo,参数)do
多元新
|>Multi.update(:serviceB,serviceB.foo_变更集(foo,params))
|>Multi.insert(:serviceC,serviceC.foo_变更集(foo,params))
结束
结束
后来:
case Repo.transaction(severelservices.run(foo,params))do
{:好的,结果}->几个服务。在提交(结果)之后
_->:错误
结束
另外@smallbutton com的回答是绝对正确的,我们通常用于此类任务。它比裸事务更健壮,因为它在启动事务之前检查变更集等
对于您的用例,代码看起来有点
defmodule多个服务都有
别名EXTO.Multi
def运行(foo,参数)do
多元新
|>Multi.update(:serviceB,serviceB.foo_变更集(foo,params))
|>Multi.insert(:serviceC,serviceC.foo_变更集(foo,params))
结束
结束
后来:
case Repo.transaction(severelservices.run(foo,params))do
{:好的,结果}->几个服务。在提交(结果)之后
_->:错误
结束