omin
I have a transaction that updates upto 3 tables and it became long and ugly. I’d love to learn more to be able to write cleaner and more efficient code.
I have a form that takes inputs to update upto 3 tables.
a. Uses external API to cache the data if it expired or doesn’t already exist.
b. build_assoc with (a) for a new data point
c. build_assoc with (a) and (b) for a new data point
Some specific questions:
- Since
transactionsshould be kept as short as possible, would you recommend fetching from the external API outside thetransaction? (This is what I’ve done but it adds complexity to the code.) - What would be to best practice to manage layers of associations? I found http://stackoverflow.com/questions/38033817/how-to-make-forms-and-transactions-play-well-in-phoenix-ecto/39415888#39415888 and I’m leaning toward the pattern matching example.
- How would you rollback multiple changesets?
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex











Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
josevalim
It seems Ecto.Multi may be exactly what you need: Ecto.Multi — Ecto v3.14.0
It answers questions 1 and 3 and it may as well answer question 2 too.
omin
Maybe. I’ve looked into it but haven’t found a way to apply associations yet.
josevalim
Since insert/update in Ecto.Multi accepts changesets, you can still build the associations in the changesets if you want to. If you can build everything with associations, then you don’t need multi because the transaction part is taken care for you when you try to introduce the changeset.
omin
Thanks for the reply @jose.
Do you think we can go through an example? I couldn’t find anything online
Would ecto rollback everything when the second or third
Repo.insertfails? Also, is there a way to cascade a changeset with multiple schemas?dimitarvp
Almost two years later: yes, according to the official docs any exception raised inside the function given to
Repo.transactionwill result in a rollback.Please note though, the third
insertin your code is not using the bang variant of the function (namely it’s notinsert!) and will thus not raise an exception so the transaction will likely still succeed with only partial success – not good.EDIT: The above is NOT true: Ecto.Multi docs
To use
Repo.transaction, do one of these:Repo.insert!,Repo.update!etc.), or…withkeyword and chain all the operations through non-bang functions and callRepo.rollbackin theelseclause – which would mean that the first failed operation will return{:error, reason}and the transaction will return that exact error so you can troubleshoot further afterwards. Or…Ecto.Multiwhich will give you even more info if an operation fails. It’s really the best way of doing such composite operations ever since it was introduced. Just have oneEcto.Multivariable and append all your operations to it, then just execute it at once:Repo.transaction(your_multi).It’s best if you don’t mix these styles. Just pick one and stick with it.
I started off using more hacky solutions and trying to be clever but nowadays I am always using
Ecto.Multiand I am very pleased with the results. The code is much easier for a human to understand as well, which is a huge bonus win.michalmuskala
This is not possible - the transaction will always either fully succeed or fully fail. If there’s a query inside a transaction that failed, but not raised the
Repo.transactionblock will return a generic error{:error, :rollback}.dimitarvp
Apologies, maybe I was misled by the documentation. I cannot see there explicitly stated that if a function returns
{:error, reason}tuple then the transaction will be rolled back.Maybe this part?
Or if not, can you point me at the docs that show my mistake?
tcoopman
dimitarvp
Thank you. I only looked at the
Repo.transactiondocs. Edited my post above, don’t want to mislead people.