Ecto.Multi without transaction

Hi all!

All examples I’ve seen so far wrap Ecto.Multi in transaction to execute - is it possible to run it outside of transaction? That is to use something else (not Repo.transaction) to execute it?

I find error handling provided by Ecto.Multi to be useful but don’t need to rollback previous changes in case further operations fail.

Thanks

Why would you want to do that? The whole point is that it wraps operations in transaction

My use case:

  • insert record (say, user) with pending status
  • make API call
  • update record status to completed in case API call succeeds

If not wrapping operations in transaction everything would be okay but with transaction everything rollbacks and I don’t have any records in users table (I’d like to have the record with pending status to be persisted).

Why not just use regular queries and functions here then? If you do not want transaction semantics (e.g., rollback on failure), do not use a transaction.

As I mentioned error handling provided by Ecto.Multi looks very nice - without it I would have to type lots of case statements to check on each operation result.

Moreover I use Ecto.Multi in similar situations and it fits nicely but in this particular case using transaction is not desirable.

I assume you are familiar with Elixir’s with syntax?

1 Like

Thanks for the hint - using with seems like a decent alternative if Ecto.Multi is not meant to be used without transaction.

I really like Ecto.Multi for composability purposes outside of its intended use case. I think there might be some momentum in the community around this as I’ve heard someone is working on pulling Multi out of Ecto and making it more generic.

I agree with @hubertlepicki. The with syntax is a good alternative. I just went through our code base and replaced a bunch of Ecto.Multi’s with with statements. I’ve recently been down this road and I think using with statements is a good approach.

2 Likes

I’m another in agreement.

My codebase is a mix of Multi Transactions and With statements. It sounds like @tap349 use case is better suited for with. Multi is coupled with database transactions. The API call breaks that pattern. Multi is better with:

  • Insert Record
  • Verify something about record in dB
  • Update record status to completed

You can also check out https://github.com/antonmi/flowex by @antonmi