foundart

foundart

Transactions- what are the basics?

I have a situation similar to create and insert 2 associated models.

In my case User has_many Others and Others belongs_to User.
I want to insert a user and an Other in one transaction.

I’m doing a put_assoc from User and it works fine. It generates 2 insert statements of course.

My question is: Do I need to wrap the insert in a Repo.transaction? I have been unable to find any documentation that talks about how the inserts are handled. If I did not wrap the insert function in a transaction, would the 2 sql statements be batched in a single transaction by default or would they be done as 2 separate transactions?

  MyModule.Repo.transaction fn ->
    MyModule.Repo.insert(changeset)
  end

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Yes, you can observe this with debug logging:

iex(5)> %Menu.Item{name: "Bar", price: 4.50, category: %Menu.Category{name: "Foo"}} |> Repo.insert!
[debug] QUERY OK db=0.3ms
begin []
[debug] QUERY OK db=6.6ms
INSERT INTO "categories" ("name","inserted_at","updated_at") VALUES ($1,$2,$3) RETURNING "id" ["Foo", {{2017, 11, 3}, {20, 21, 34, 814485}}, {{2017, 11, 3}, {20, 21, 34, 817077}}]
[debug] QUERY OK db=5.0ms
INSERT INTO "items" ("category_id","name","price","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [4, "Bar", #Decimal<4.5>, {{2017, 11, 3}, {20, 21, 34, 834005}}, {{2017, 11, 3}, {20, 21, 34, 834009}}]
[debug] QUERY OK db=0.8ms
commit []

Note the begin and commit lines. Those are the beginning and end of the transaction respectively.

szsoppa

szsoppa

If anyone coming to this topic needs more tips on Ecto.Multi and transactions in general, we’ve written a post about it: How database transactions work in Ecto and why Elixir makes it awesome? :wink:

theangryangel

theangryangel

You probably want an Ecto.Multi rather than using transactions directly as you get a bunch of extra stuff that you don’t get with Repo.transaction

foundart

foundart

Well, since I don’t know what I get with transactions, I’d really like to understand more about them first, so I can understand what advantages I’m getting with Ecto.Multi.

theangryangel

theangryangel

A transaction is a sequence of operations performed as a single unit of work. Or more simply, if a statement in the transaction fails the previous statements will get automatically rolled back (in Ecto), and no further operations are carried out. If you’re using transactions manually you can perform special behaviours on rollback, if simply rolling back isn’t enough.

Ecto.Multi works hand in hand with Repo.transaction and provides a bunch of useful stuff on top of transactions. i.e. easy inspection and returns, that using Repo.transaction directly you’d probably end up implementing anyway.

Where Next?

Popular in Questions Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement