Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何将诸如after_commit回调之类的东西附加到一个Ecto事务?_Elixir_Ecto - Fatal编程技术网

Elixir 如何将诸如after_commit回调之类的东西附加到一个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, _} &

有没有一种方法可以将回调附加到提交事务后调用的Ecto事务?我在找类似的东西

我正在处理的用例是在执行操作后引发副作用。例如,在下面的代码中,我想在
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
{:好的,结果}->几个服务。在提交(结果)之后
_->:错误
结束