# Django 6.0.7 documentation

# Databastransaktioner

Django ger dig några sätt att kontrollera hur databastransaktioner hanteras.

## Hantering av databastransaktioner

### Djangos standardbeteende för transaktioner

Djangos standardbeteende är att köra i autocommit-läge. Varje fråga bekräftas omedelbart till databasen, såvida inte en transaktion är aktiv. Se nedan för detaljer.

Django använder transaktioner eller sparpunkter automatiskt för att garantera integriteten i ORM-operationer som kräver flera frågor, särskilt delete() och update() frågor.

Djangos klass `TestCase` kapslar också in varje test i en transaktion av prestandaskäl.

### Koppling av transaktioner till HTTP-förfrågningar

Ett vanligt sätt att hantera transaktioner på webben är att varje förfrågan paketeras i en transaktion. Ange `ATOMIC_REQUESTS` till `True` i konfigurationen för varje databas för vilken du vill aktivera detta beteende.

Det fungerar på följande sätt. Innan en view-funktion anropas startar Django en transaktion. Om svaret produceras utan problem, förbinder Django transaktionen. Om vyn producerar ett undantag rullar Django tillbaka transaktionen.

Du kan utföra undertransaktioner med hjälp av sparpunkter i din vykod, vanligtvis med kontexthanteraren `atomic()`. I slutet av vyn kommer dock antingen alla eller inga av ändringarna att bekräftas.

Varning

Även om enkelheten i den här transaktionsmodellen är tilltalande, gör den den också ineffektiv när trafiken ökar. Att öppna en transaktion för varje vy innebär en viss overhead. Effekten på prestandan beror på frågemönstren i din applikation och på hur väl din databas hanterar låsning.

Transaktioner per förfrågan och strömmande svar

När en vy returnerar en `StreamingHttpResponse`, kommer läsning av innehållet i svaret ofta att exekvera kod för att generera innehållet. Eftersom vyn redan har returnerats körs sådan kod utanför transaktionen.

Generellt sett är det inte tillrådligt att skriva till databasen medan ett streamingsvar genereras, eftersom det inte finns något vettigt sätt att hantera fel efter att svaret har börjat skickas.

I praktiken innebär denna funktion att varje vyfunktion omsluts av dekoratorn `atomic()` som beskrivs nedan.

Observera att endast exekveringen av din vy är innesluten i transaktionerna. Middleware körs utanför transaktionen, och det gör även rendering av mallsvar.

När `ATOMIC_REQUESTS` är aktiverat är det fortfarande möjligt att förhindra att vyer körs i en transaktion.

non_atomic_requests(using=None)

  Denna dekorator upphäver effekten av `ATOMIC_REQUESTS` för en given vy:

      from django.db import transaction

      @transaction.non_atomic_requests
      def my_view(request):
          do_stuff()

      @transaction.non_atomic_requests(using="other")
      def my_other_view(request):
          do_stuff_on_the_other_database()

  Det fungerar bara om det tillämpas på själva vyn.

### Explicit kontroll av transaktioner

Django tillhandahåller ett enda API för att styra databastransaktioner.

atomic(using=None, savepoint=True, durable=False)

  Atomicity är den definierande egenskapen för databastransaktioner. med `atomic` kan vi skapa ett kodblock inom vilket atomiciteten i databasen garanteras. Om kodblocket slutförs framgångsrikt överförs ändringarna till databasen. Om det finns ett undantag rullas ändringarna tillbaka.

  `atomiska` block kan vara nästlade. I detta fall, när ett inre block slutförs framgångsrikt, kan dess effekter fortfarande rullas tillbaka om ett undantag uppstår i det yttre blocket vid en senare tidpunkt.

  Ibland är det bra att se till att ett `atomiskt` block alltid är det yttersta `atomiska` blocket, så att alla databasändringar bekräftas när blocket avslutas utan fel. Detta kallas för durability och kan uppnås genom att ställa in `durable=True`. Om det `atomiska` blocket är kapslat i ett annat block ger det upphov till ett `RuntimeError`.

  `atomic` is usable both as a decorator:

      from django.db import transaction

      @transaction.atomic
      def viewfunc(request):
          # This code executes inside a transaction.
          do_stuff()

  and as a context manager:

      from django.db import transaction

      def viewfunc(request):
          # This code executes in autocommit mode (Django's default).
          do_stuff()

          with transaction.atomic():
              # This code executes inside a transaction.
              do_more_stuff()

  Genom att paketera `atomic` i ett try/except-block möjliggörs en naturlig hantering av integritetsfel:

      from django.db import IntegrityError, transaction

      @transaction.atomic
      def viewfunc(request):
          create_parent()

          try:
              with transaction.atomic():
                  generate_relationships()
          except IntegrityError:
              handle_exception()

          add_children()

  I det här exemplet kan du, även om `generate_relationships()` orsakar ett databasfel genom att bryta en integritetsbegränsning, köra frågor i `add_children()`, och ändringarna från `create_parent()` finns fortfarande kvar och är bundna till samma transaktion. Observera att alla operationer som försökts i `generate_relationships()` redan kommer att ha rullats tillbaka på ett säkert sätt när `handle_exception()` anropas, så undantagshanteraren kan också operera på databasen om det behövs.

  Undvik att fånga undantag inuti `atomic`!

  När ett `atomiskt` block avslutas tittar Django på om det avslutades normalt eller med ett undantag för att avgöra om det ska bekräftas eller rullas tillbaka. Om du fångar och hanterar undantag inuti ett `atomiskt` block kan du dölja för Django att ett problem har uppstått. Detta kan resultera i oväntat beteende.

  Detta är främst ett problem för `DatabaseError` och dess underklasser som `IntegrityError`. Efter ett sådant fel bryts transaktionen och Django kommer att utföra en rollback i slutet av det `atomiska` blocket. Om du försöker köra databasfrågor innan rollback sker, kommer Django att höja en `TransactionManagementError`. Du kan också stöta på detta beteende när en ORM-relaterad signalhanterare ger upphov till ett undantag.

  Det korrekta sättet att fånga upp databasfel är runt ett `atomiskt` block som visas ovan. Om det behövs, lägg till ett extra `atomic` block för detta ändamål. Det här mönstret har en annan fördel: det avgränsar uttryckligen vilka operationer som ska rullas tillbaka om ett undantag inträffar.

  Om du fångar upp undantag som orsakas av råa SQL-frågor är Djangos beteende ospecificerat och databasberoende.

  Du kan behöva återställa appstatus manuellt när du rullar tillbaka en transaktion.

  Värdena för en modells fält återställs inte när en transaktion rullas tillbaka. Detta kan leda till ett inkonsekvent modelltillstånd om du inte manuellt återställer de ursprungliga fältvärdena.

  Till exempel, om `MyModel` har ett `active`-fält, säkerställer detta utdrag att `if obj.active`-kontrollen i slutet använder rätt värde om uppdateringen av `active` till `True` misslyckas i transaktionen:

      from django.db import DatabaseError, transaction

      obj = MyModel(active=False)
      obj.active = True
      try:
          with transaction.atomic():
              obj.save()
      except DatabaseError:
          obj.active = False

      if obj.active:
          ...

  Detta gäller även alla andra mekanismer som kan hålla appens tillstånd, t.ex. cache eller globala variabler. Om koden t.ex. proaktivt uppdaterar data i cacheminnet efter att ett objekt har sparats, rekommenderas att du använder transaction.on_commit() istället, för att skjuta upp cacheändringar tills transaktionen faktiskt genomförs.

  För att garantera atomicitet inaktiverar `atomic` vissa API:er. Om du försöker göra en commit, roll back eller ändra autocommit-läget för databasanslutningen inom ett `atomic`-block kommer ett undantag att uppstå.

  `atomic` tar ett `using` argument som bör vara namnet på en databas. Om detta argument inte tillhandahålls använder Django databasen `"default"`.

  Under huven, Djangos kod för transaktionshantering:

  - öppnar en transaktion när den går in i det yttersta `atomiska` blocket;

  - skapar en sparpunkt när du går in i ett inre `atomiskt` block;

  - frigör eller rullar tillbaka till sparpunkten när ett inre block avslutas;

  - genomför eller rullar tillbaka transaktionen när det yttersta blocket avslutas.

  Du kan inaktivera skapandet av sparpunkter för inre block genom att ställa in argumentet `savepoint` till `False`. Om ett undantag inträffar kommer Django att utföra en rollback genom att avsluta det första överordnade blocket med en savepoint om det finns en, och det yttersta blocket annars. Atomicitet garanteras fortfarande av den yttre transaktionen. Detta alternativ bör endast användas om omkostnaderna för sparpunkter är märkbara. Det har nackdelen att det bryter mot felhanteringen som beskrivs ovan.

  Du kan använda `atomic` när autocommit är avstängt. Det kommer bara att använda sparpunkter, även för det yttersta blocket.

Överväganden om prestanda

Öppna transaktioner innebär en prestandakostnad för din databasserver. För att minimera denna overhead bör du hålla dina transaktioner så korta som möjligt. Detta är särskilt viktigt om du använder `atomic()` i långvariga processer, utanför Djangos request / response-cykel.

## Autocommit

### Varför Django använder autocommit

I SQL-standarderna startar varje SQL-fråga en transaktion, såvida inte en transaktion redan är aktiv. Sådana transaktioner måste då uttryckligen bekräftas eller rullas tillbaka.

Detta är inte alltid bekvämt för applikationsutvecklare. För att lindra detta problem tillhandahåller de flesta databaser ett autocommit-läge. När autocommit är aktiverat och ingen transaktion är aktiv, blir varje SQL-fråga inkapslad i en egen transaktion. Med andra ord startar inte bara varje sådan fråga en transaktion, utan transaktionen blir också automatiskt bekräftad eller rullad tillbaka, beroende på om frågan lyckades.

PEP 249, Python Database API Specification v2.0, kräver att autocommit initialt ska vara avstängt. Django åsidosätter denna standard och slår på autocommit.

För att undvika detta kan du avaktivera transaktionshanteringen, men det rekommenderas inte.

### Avaktivera transaktionshantering

Du kan helt inaktivera Djangos transaktionshantering för en viss databas genom att ställa in `AUTOCOMMIT` till `False` i dess konfiguration. Om du gör detta kommer Django inte att aktivera autocommit och kommer inte att utföra några commits. Du kommer att få det vanliga beteendet hos det underliggande databasbiblioteket.

Detta kräver att du uttryckligen bekräftar varje transaktion, även de som startas av Django eller av tredjepartsbibliotek. Därför används detta bäst i situationer där du vill köra din egen transaktionskontrollerande middleware eller göra något riktigt konstigt.

## Utföra åtgärder efter commit

Ibland behöver du utföra en åtgärd som är relaterad till den aktuella databastransaktionen, men bara om transaktionen har överförts. Exempel på detta kan vara en bakgrundsuppgift, ett e-postmeddelande eller en inaktivering av cacheminnet.

`on_commit()` gör det möjligt att registrera callbacks som kommer att utföras efter att den öppna transaktionen har bekräftats:

on_commit(func, using=None, robust=False)

Skicka en funktion, eller en valfri anropsbar funktion, till `on_commit()`:

    from django.db import transaction

    def send_welcome_email(): ...

    transaction.on_commit(send_welcome_email)

Callbacks får inte några argument, men du kan binda dem med `functools.partial()`:

    from functools import partial

    for user in users:
        transaction.on_commit(partial(send_invite_email, user=user))

Callbacks anropas efter att den öppna transaktionen har bekräftats. Om transaktionen i stället rullas tillbaka (vanligtvis när ett ohanterat undantag uppstår i ett `atomic()`-block), kommer återkallelsen att kasseras och aldrig anropas.

Om du anropar `on_commit()` medan det inte finns någon öppen transaktion, kommer återuppringningen att utföras omedelbart.

Det är ibland användbart att registrera callbacks som kan misslyckas. Genom att ange `robust=True` kan nästa callback utföras även om den aktuella callbacken ger upphov till ett undantag. Alla fel som härrör från Pythons klass `Exception` fångas upp och loggas till loggern `django.db.backends.base`.

Du kan använda `TestCase.captureOnCommitCallbacks()` för att testa callbacks som registrerats med `on_commit()`.

### Spara poäng

Sparpunkter (d.v.s. nästlade `atomic()`-block) hanteras korrekt. Det vill säga, en `on_commit()` callable som registreras efter en savepoint (i ett nästlat `atomic()` block) kommer att anropas efter att den yttre transaktionen har committats, men inte om en rollback till den savepointen eller någon tidigare savepoint inträffade under transaktionen:

    with transaction.atomic():  # Outer atomic, start a new transaction
        transaction.on_commit(foo)

        with transaction.atomic():  # Inner atomic block, create a savepoint
            transaction.on_commit(bar)

    # foo() and then bar() will be called when leaving the outermost block

Å andra sidan, när en sparpunkt rullas tillbaka (på grund av att ett undantag har uppstått), kommer den inre anropsbarheten inte att anropas:

    with transaction.atomic():  # Outer atomic, start a new transaction
        transaction.on_commit(foo)

        try:
            with transaction.atomic():  # Inner atomic block, create a savepoint
                transaction.on_commit(bar)
                raise SomeError()  # Raising an exception - abort the savepoint
        except SomeError:
            pass

    # foo() will be called, but not bar()

### Verkställighetsordning

On-commit-funktioner för en viss transaktion utförs i den ordning de registrerades.

### Hantering av undantag

Om en on-commit-funktion som registrerats med `robust=False` inom en viss transaktion ger upphov till ett undantag som inte fångats upp, kommer inga senare registrerade funktioner i samma transaktion att köras. Detta är samma beteende som om du själv hade kört funktionerna sekventiellt utan `on_commit()`.

### Tidpunkt för verkställande

Dina callbacks exekveras efter en lyckad commit, så ett fel i en callback kommer inte att leda till att transaktionen rullas tillbaka. De exekveras villkorligt när transaktionen lyckas, men de är inte del av transaktionen. För de avsedda användningsfallen (e-postmeddelanden, bakgrundsuppgifter etc.) bör detta vara bra. Om det inte är det (om din uppföljningsåtgärd är så kritisk att dess misslyckande bör innebära att själva transaktionen misslyckas), då vill du inte använda `on_commit()`-hook. Istället kanske du vill ha two-phase commit som psycopg Two-Phase Commit protocol support och optional Two-Phase Commit Extensions in the Python DB-API specification.

Callbacks körs inte förrän autocommit återställs på anslutningen efter commit (eftersom alla frågor som görs i en callback annars skulle öppna en implicit transaktion och förhindra att anslutningen går tillbaka till autocommit-läge).

När funktionen är i autocommit-läge och utanför ett `atomic()`-block kommer den att köras omedelbart, inte vid commit.

On-commit-funktioner fungerar endast med autocommit mode och `atomic()` (eller `ATOMIC_REQUESTS`) transaktions-API. Om du anropar `on_commit()` när autocommit är inaktiverat och du inte befinner dig inom ett atomic block kommer det att resultera i ett fel.

### Användning i tester

Djangos `TestCase`-klass omsluter varje test i en transaktion och rullar tillbaka transaktionen efter varje test för att tillhandahålla testisolering. Detta innebär att ingen transaktion någonsin faktiskt genomförs, vilket innebär att dina `on_commit()` callbacks aldrig kommer att köras.

Du kan övervinna denna begränsning genom att använda `TestCase.captureOnCommitCallbacks()`. Detta fångar dina `on_commit()` callbacks i en lista, så att du kan göra påståenden om dem, eller emulera transaktionen genom att anropa dem.

Ett annat sätt att övervinna begränsningen är att använda `TransactionTestCase` istället för `TestCase`. Detta kommer att innebära att dina transaktioner är bekräftade och att callbacks kommer att köras. Men `TransactionTestCase` rensar databasen mellan testerna, vilket är betydligt långsammare än `TestCase`:s isolering.

### Varför ingen rollback-hook?

En rollback-hook är svårare att implementera på ett robust sätt än en commit-hook, eftersom en mängd olika saker kan orsaka en implicit rollback.

Om t.ex. din databasanslutning bryts på grund av att din process dödades utan möjlighet att stängas av på ett elegant sätt, kommer din rollback-hook aldrig att köras.

Men det finns en lösning: istället för att göra något under det atomiska blocket (transaktionen) och sedan ångra det om transaktionen misslyckas, använd `on_commit()` för att skjuta upp det till efter att transaktionen har lyckats. Det är mycket lättare att ångra något som man aldrig gjorde från början!

## API:er på låg nivå

Varning

Föredra alltid `atomic()` om det alls är möjligt. Det tar hänsyn till varje databas egenheter och förhindrar ogiltiga operationer.

API:erna på låg nivå är bara användbara om du implementerar din egen transaktionshantering.

### Autocommit

Django tillhandahåller ett API i modulen `django.db.transaction` för att hantera autocommit-läget för varje databasanslutning.

get_autocommit(using=None)

set_autocommit(autocommit, using=None)

Dessa funktioner tar ett `using` argument som bör vara namnet på en databas. Om det inte tillhandahålls använder Django databasen `"default"`.

Autocommit är initialt aktiverat. Om du stänger av den är det ditt ansvar att återställa den.

När du stänger av autocommit får du standardbeteendet för din databasadapter, och Django hjälper dig inte. Även om det beteendet specificeras i PEP 249, är implementeringar av adaptrar inte alltid konsekventa med varandra. Granska dokumentationen för den adapter du använder noggrant.

Du måste se till att ingen transaktion är aktiv, vanligtvis genom att utfärda en `commit()` eller en `rollback()`, innan du slår på autocommit igen.

Django kommer att vägra att stänga av autocommit när ett `atomic()`-block är aktivt, eftersom det skulle bryta atomiciteten.

### Transaktioner

En transaktion är en atomuppsättning av databasfrågor. Även om ditt program kraschar garanterar databasen att antingen alla ändringar kommer att tillämpas eller ingen av dem.

Django tillhandahåller inte ett API för att starta en transaktion. Det förväntade sättet att starta en transaktion är att inaktivera autocommit med `set_autocommit()`.

När du är i en transaktion kan du välja att antingen tillämpa de ändringar du har utfört fram till denna punkt med `commit()`, eller att avbryta dem med `rollback()`. Dessa funktioner är definierade i `django.db.transaction`.

commit(using=None)

rollback(using=None)

Dessa funktioner tar ett `using` argument som bör vara namnet på en databas. Om det inte tillhandahålls använder Django databasen `"default"`.

Django kommer att vägra att göra en commit eller rollback när ett `atomic()` block är aktivt, eftersom det skulle bryta atomiciteten.

### Spara poäng

En savepoint är en markör inom en transaktion som gör att du kan rulla tillbaka en del av en transaktion, snarare än hela transaktionen. Savepoints är tillgängliga med backends SQLite, PostgreSQL, Oracle och MySQL (när du använder InnoDB-lagringsmotorn). Andra backends tillhandahåller savepoint-funktionerna, men de är tomma operationer - de gör faktiskt ingenting.

Savepoints är inte särskilt användbara om du använder autocommit, standardbeteendet i Django. Men när du öppnar en transaktion med `atomic()` bygger du upp en serie databasoperationer i väntan på en commit eller rollback. Om du utfärdar en rollback, rullas hela transaktionen tillbaka. Savepoints ger möjlighet att utföra en finkornig rollback, snarare än den fullständiga rollback som skulle utföras av `transaction.rollback()`.

När dekoratorn `atomic()` är nästlad skapar den en sparpunkt för att möjliggöra partiell commit eller rollback. Du uppmuntras starkt att använda `atomic()` i stället för de funktioner som beskrivs nedan, men de är fortfarande en del av det offentliga API:et och det finns ingen plan för att avskaffa dem.

Each of these functions takes a `using` argument which should be the name of a database for which the behavior applies. If no `using` argument is provided then the `"default"` database is used.

Sparpunkter styrs av tre funktioner i `django.db.transaction`:

savepoint(using=None)

  Ersatt sedan version 6.1: `savepoint` has been renamed to `savepoint_create`.

  Skapar en ny sparpunkt. Detta markerar en punkt i transaktionen som är känd för att vara i ett ”bra” tillstånd. Returnerar sparpunktens ID (`sid`).

savepoint_create(using=None)
  New in Django 6.1.

  Skapar en ny sparpunkt. Detta markerar en punkt i transaktionen som är känd för att vara i ett ”bra” tillstånd. Returnerar sparpunktens ID (`sid`).

savepoint_commit(sid, using=None)

  Frigör lagringspunkten `sid`. De ändringar som gjorts sedan sparpunkten skapades blir en del av transaktionen.

savepoint_rollback(sid, using=None)

  Rullar tillbaka transaktionen till sparpunkten `sid`.

Dessa funktioner gör ingenting om sparpunkter inte stöds eller om databasen är i autocommit-läge.

Dessutom finns det en nyttofunktion:

clean_savepoints(using=None)

  Återställer räknaren som används för att generera unika ID:n för sparpunkter.

Följande exempel visar hur du kan använda savepoints:

    from django.db import transaction

    # open a transaction
    @transaction.atomic
    def viewfunc(request):
        a.save()
        # transaction now contains a.save()

        sid = transaction.savepoint_create()

        b.save()
        # transaction now contains a.save() and b.save()

        if want_to_keep_b:
            transaction.savepoint_commit(sid)
            # open transaction still contains a.save() and b.save()
        else:
            transaction.savepoint_rollback(sid)
            # open transaction now contains only a.save()

Savepoints kan användas för att återhämta sig från ett databasfel genom att utföra en partiell rollback. Om du gör detta inuti ett `atomic()`-block kommer hela blocket ändå att rullas tillbaka, eftersom det inte vet att du har hanterat situationen på en lägre nivå! För att förhindra detta kan du styra rollback-beteendet med följande funktioner.

get_rollback(using=None)

set_rollback(rollback, using=None)

Om du ställer in rollback-flaggan till `True` tvingas en rollback när du lämnar det innersta atomiska blocket. Detta kan vara användbart för att utlösa en rollback utan att skapa ett undantag.

Om du ställer in den på `False` förhindras en sådan rollback. Innan du gör det, se till att du har rullat tillbaka transaktionen till en känd bra sparpunkt inom det aktuella atomiska blocket! Annars bryter du atomiciteten och datakorruption kan uppstå.

## Databasspecifika anteckningar

### Sparpunkter i SQLite

SQLite stöder visserligen sparpunkter, men ett fel i `sqlite3`-modulens design gör att de knappast är användbara.

När autocommit är aktiverat är savepoints inte meningsfulla. När den är inaktiverad, gör `sqlite3` implicit commits före savepoint-satser. (Faktum är att den committar före alla andra satser än `SELECT`, `INSERT`, `UPDATE`, `DELETE` och `REPLACE`) Denna bugg har två konsekvenser:

- API:erna på låg nivå för sparpunkter kan endast användas inom en transaktion, dvs. inom ett `atomic()`-block.

- Det är omöjligt att använda `atomic()` när autocommit är avstängt.

### Transaktioner i MySQL

Om du använder MySQL kan det hända att dina tabeller stöder transaktioner eller inte; det beror på din MySQL-version och de tabelltyper du använder. (Med ”tabelltyper” menar vi något som ”InnoDB” eller ”MyISAM”.) MySQL-transaktionens särdrag ligger utanför ramen för denna artikel, men MySQL-webbplatsen har information om MySQL-transaktioner.

Om din MySQL-konfiguration inte stöder transaktioner kommer Django alltid att fungera i autocommit-läge: uttalanden kommer att utföras och bekräftas så snart de anropas. Om din MySQL-installation har stöd för transaktioner, kommer Django att hantera transaktioner enligt vad som förklaras i detta dokument.

### Hantering av undantag inom PostgreSQL-transaktioner

Observera

Detta avsnitt är endast relevant om du implementerar din egen transaktionshantering. Detta problem kan inte uppstå i Djangos standardläge och `atomic()` hanterar det automatiskt.

Inuti en transaktion, när ett anrop till en PostgreSQL-markör ger upphov till ett undantag (vanligtvis `` IntegrityError``), kommer all efterföljande SQL i samma transaktion att misslyckas med felet ”aktuell transaktion avbryts, frågor ignoreras till slutet av transaktionsblocket”. Även om den grundläggande användningen av `` save () `` sannolikt inte kommer att ge upphov till ett undantag i PostgreSQL, finns det mer avancerade användningsmönster som kan, till exempel att spara objekt med unika fält, spara med flaggan `force_insert` / `force_update` eller anropa anpassad SQL.

Det finns flera sätt att återhämta sig från den här typen av fel.

#### Återställning av transaktion

Det första alternativet är att rulla tillbaka hela transaktionen. Till exempel:

    a.save()  # Succeeds, but may be undone by transaction rollback
    try:
        b.save()  # Could throw exception
    except IntegrityError:
        transaction.rollback()
    c.save()  # Succeeds, but a.save() may have been undone

Anrop av `transaction.rollback()` rullar tillbaka hela transaktionen. Alla obekräftade databasoperationer kommer att gå förlorade. I det här exemplet skulle de ändringar som gjordes av `a.save()` gå förlorade, även om den operationen inte gav upphov till något fel i sig.

#### Återställning av sparpunkt

Du kan använda :ref:` savepoints <topics-db-transactions-savepoints> för att styra omfattningen av en återställning. Innan du utför en databasoperation som kan misslyckas kan du ange eller uppdatera sparpunkten; på så sätt kan du, om operationen misslyckas, rulla tillbaka den enskilda felaktiga operationen i stället för hela transaktionen. Till exempel:

    a.save()  # Succeeds, and never undone by savepoint rollback
    sid = transaction.savepoint_create()
    try:
        b.save()  # Could throw exception
        transaction.savepoint_commit(sid)
    except IntegrityError:
        transaction.savepoint_rollback(sid)
    c.save()  # Succeeds, and a.save() is never undone

I det här exemplet kommer `a.save()` inte att ångras i det fall `b.save()` ger upphov till ett undantag.