Elixir & Phoenix: Scalable Backend Development · Lekcja

Transakcje i Ecto.Multi

Grupuj wiele operacji bazodanowych w jednostki atomowe za pomocą transakcji Repo i kompozytowalnej struktury Ecto.Multi.

Lekcja 4 z 413 kroki

Transakcje i Ecto.Multi to bezpłatna lekcja Elixir & Phoenix: Scalable Backend Development na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Elixir & Phoenix: Scalable Backend Development, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Elixir & Phoenix: Scalable Backend Development zawiera 4 lekcji w sumie.

Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.

Why Transactions?

A transaction bundles several operations so they all succeed or all roll back together, keeping data consistent.

Repo.transaction with a Function

The simplest form runs a function; if it returns normally the transaction commits, if it raises it rolls back.

Repo.transaction(fn ->
  Repo.insert!(%Account{balance: 100})
  Repo.insert!(%Log{action: "created"})
end)

Manual Rollback

Inside the function you can abort explicitly with Repo.rollback/1, which returns {:error, reason}.

Repo.transaction(fn ->
  case withdraw(account, 50) do
    {:ok, acc} -> acc
    {:error, r} -> Repo.rollback(r)
  end
end)

The Problem with Nested Functions

Function-based transactions get hard to read and reuse when steps depend on earlier results. Ecto.Multi solves this declaratively.

Building an Ecto.Multi

Ecto.Multi is a struct that accumulates named operations without touching the database until run.

alias Ecto.Multi
multi =
  Multi.new()
  |> Multi.insert(:user, %User{name: "Ada"})

Chaining Operations

Each operation gets a unique name, letting you reference earlier results and inspect them later.

Multi.new()
|> Multi.insert(:user, user_changeset)
|> Multi.insert(:profile, profile_changeset)

Depending on Earlier Steps

Pass a function to use the results of previous steps. It receives the repo and a map of completed operations.

Multi.new()
|> Multi.insert(:user, user_changeset)
|> Multi.run(:welcome, fn _repo, %{user: user} ->
  send_welcome(user)
end)

Running the Multi

Repo.transaction/1 executes the whole Multi atomically and returns {:ok, results} or an error tuple.

case Repo.transaction(multi) do
  {:ok, %{user: user}} -> {:ok, user}
  {:error, step, reason, _} -> {:error, step, reason}
end

Pinpointing Failures

On failure the error tuple names exactly which step failed and gives the changes made so far (which were rolled back).

{:error, :profile, changeset, _changes_so_far}

Other Multi Operations

Multi supports update, delete, update_all, and delete_all, mirroring Repo functions.

Multi.new()
|> Multi.update(:acc, changeset)
|> Multi.delete_all(:logs, old_logs_query)

Composability Wins

Because a Multi is just data, you can build it in pieces across functions and append more steps before running it, improving testability.

def base_multi, do: Multi.new() |> Multi.insert(:user, cs)
# elsewhere
base_multi() |> Multi.insert(:audit, audit_cs) |> Repo.transaction()

Quick Check

Test your transaction knowledge.

Recap

You made database changes atomic:

  • Repo.transaction with a function commits or rolls back together
  • Repo.rollback aborts explicitly
  • Ecto.Multi composes named steps as data
  • Failures return the failing step name and roll back everything
Bezpłatny start

Ucz się Elixir dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
12
Lekcje
48

Często zadawane pytania

Czy lekcja „Transakcje i Ecto.Multi” jest bezpłatna?

Tak — pełny tekst „Transakcje i Ecto.Multi” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Elixir & Phoenix: Scalable Backend Development, przejdź na CoddyKit PRO. Kurs Elixir & Phoenix: Scalable Backend Development zawiera 4 lekcji w sumie.

Co nauczysz się w „Transakcje i Ecto.Multi”?

Grupuj wiele operacji bazodanowych w jednostki atomowe za pomocą transakcji Repo i kompozytowalnej struktury Ecto.Multi. Ćwiczysz Elixir & Phoenix: Scalable Backend Development z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Elixir & Phoenix: Scalable Backend Development?

Nie wymagamy żadnego doświadczenia. Elixir & Phoenix: Scalable Backend Development w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Transakcje i Ecto.Multi”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Elixir & Phoenix: Scalable Backend Development?

Tak. Każda lekcja Elixir & Phoenix: Scalable Backend Development zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Schematy Ecto i migracje bazy danych
  2. Repo, Changesets i zapytania
  3. Powiązania i osadzone schematy
  4. Transakcje i Ecto.Multi
← Powrót do Elixir & Phoenix: Scalable Backend Development