---
title: "Transaksi basisdata"
version: 1.9
locale: id
source: https://docs.djangoproject.com/id/1.9/topics/db/transactions/
canonical: https://djangodocs.dev/id/1.9/topics/db/transactions/
---
# Transaksi basisdata

Django memberikan anda sedikit cara mengendalikan bagaimana transaksi basisdata dikelola.

## Mengelola transaksi basisdata

### Kebiasaan transaksi awal Django

Kebiasaan awal Django adalah menjalankan suasana penyeraahn otomatis. Setiap query segera diserahkan ke basisdata, meskipun transaksi adalah aktif. [Lihat dibawah ini untuk rincian](#autocommit-details).

Django menggunakan transaksi atau titiksimpan otomatis untuk menjamin kesatuan dari operasi ORM yang membutuhkan banyak query, khususnya query [delete()](/id/1.9/topics/db/queries/#topics-db-queries-delete) dan [update()](/id/1.9/topics/db/queries/#topics-db-queries-update).

Django's [`TestCase`](/id/1.9/topics/testing/tools/#django.test.TestCase) class also wraps each test in a
transaction for performance reasons.

### Tying transactions to HTTP requests

Cara umum untuk menangani transaksi di jaringan adalah membungkus setiap permintaan di transaksi. Setel [`ATOMIC_REQUESTS`](/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS) ke `True` di konfigurasi dari setiap basisdata untuk anda ingin adakan kebiasaan ini.

It works like this. Before calling a view function, Django starts a
transaction. If the response is produced without problems, Django commits the
transaction. If the view produces an exception, Django rolls back the
transaction.

You may perform subtransactions using savepoints in your view code, typically
with the [`atomic()`](#django.db.transaction.atomic) context manager. However, at the end of the view,
either all or none of the changes will be committed.

> **Warning**
>
> While the simplicity of this transaction model is appealing, it also makes it
> inefficient when traffic increases. Opening a transaction for every view has
> some overhead. The impact on performance depends on the query patterns of your
> application and on how well your database handles locking.

> **Per-request transactions and streaming responses**
>
> When a view returns a [`StreamingHttpResponse`](/id/1.9/ref/request-response/#django.http.StreamingHttpResponse), reading
> the contents of the response will often execute code to generate the
> content. Since the view has already returned, such code runs outside of
> the transaction.
>
> Generally speaking, it isn't advisable to write to the database while
> generating a streaming response, since there's no sensible way to handle
> errors after starting to send the response.

In practice, this feature simply wraps every view function in the [`atomic()`](#django.db.transaction.atomic)
decorator described below.

Note that only the execution of your view is enclosed in the transactions.
Middleware runs outside of the transaction, and so does the rendering of
template responses.

When [`ATOMIC_REQUESTS`](/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS) is enabled, it's
still possible to prevent views from running in a transaction.

#### `non_atomic_requests(using=None)`

This decorator will negate the effect of [`ATOMIC_REQUESTS`](/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS) for a given view:

```
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()
```

It only works if it's applied to the view itself.

### Mengendalikan transaksi secara eksplisit

Django provides a single API to control database transactions.

#### `atomic(using=None, savepoint=True)`

Atomicity is the defining property of database transactions. `atomic`
allows us to create a block of code within which the atomicity on the
database is guaranteed. If the block of code is successfully completed, the
changes are committed to the database. If there is an exception, the
changes are rolled back.

`atomic` blocks can be nested. In this case, when an inner block
completes successfully, its effects can still be rolled back if an
exception is raised in the outer block at a later point.

`atomic` is usable both as a [decorator](https://docs.python.org/3/glossary.html#term-decorator):

```
from django.db import transaction

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

dan sebagai [context manager](https://docs.python.org/3/glossary.html#term-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()
```

Wrapping `atomic` in a try/except block allows for natural handling of
integrity errors:

```
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()
```

In this example, even if `generate_relationships()` causes a database
error by breaking an integrity constraint, you can execute queries in
`add_children()`, and the changes from `create_parent()` are still
there. Note that any operations attempted in `generate_relationships()`
will already have been rolled back safely when `handle_exception()` is
called, so the exception handler can also operate on the database if
necessary.

> **Avoid catching exceptions inside atomic!**
>
> When exiting an `atomic` block, Django looks at whether it's exited
> normally or with an exception to determine whether to commit or roll
> back. If you catch and handle exceptions inside an `atomic` block,
> you may hide from Django the fact that a problem has happened. This
> can result in unexpected behavior.
>
> This is mostly a concern for [`DatabaseError`](/id/1.9/ref/exceptions/#django.db.DatabaseError) and its
> subclasses such as [`IntegrityError`](/id/1.9/ref/exceptions/#django.db.IntegrityError). After such an
> error, the transaction is broken and Django will perform a rollback at
> the end of the `atomic` block. If you attempt to run database
> queries before the rollback happens, Django will raise a
> [`TransactionManagementError`](/id/1.9/ref/exceptions/#django.db.transaction.TransactionManagementError). You may
> also encounter this behavior when an ORM-related signal handler raises
> an exception.
>
> The correct way to catch database errors is around an `atomic` block
> as shown above. If necessary, add an extra `atomic` block for this
> purpose. This pattern has another advantage: it delimits explicitly
> which operations will be rolled back if an exception occurs.
>
> If you catch exceptions raised by raw SQL queries, Django's behavior
> is unspecified and database-dependent.

In order to guarantee atomicity, `atomic` disables some APIs. Attempting
to commit, roll back, or change the autocommit state of the database
connection within an `atomic` block will raise an exception.

`atomic` takes a `using` argument which should be the name of a
database. If this argument isn't provided, Django uses the `"default"`
database.

Dibawah tenda, kode pengelolaan transaksi Django:

- membuka sebuah transaksi ketika memasukkan blok `atomic` paling luar;
- membuat titiksimpan ketika memasukkan blok `atomic` paling dalam;
- melepaskan atau digulung kembali ke titik simpan ketika keluar blok paling dalam;
- menyerahkan atau gulung kembali transaksi ketika keluar blok paling luar

Anda dapat meniadakan pembuatan dari titik simpan untuk blok paling dalam dengan mengatur argumen `savepoint` ke `False`. Jika sebuah pengecualian muncul, DJango akan melakukan gulunh kembali ketika keluar blok induk pertama dengan sebuah titik simpan jika ada, dan blok paling luar jika tidak. Atomicity masih dijamin oleh transaksi paling luar. Pilihan ini harus hanya digunakan jika kelebihan dari titik simpan dapat dilihat. Itu mempunyai kekurangan dari memecahkan penanganan kesalahan yang digambarkan diatas.

Anda dapat menggunakan `atomic` ketika penyerahan otomatis dimatikan. Itu akan hanya menggunakan titik simpan, bahkan untuk blok paling luar.

> **Changed in Django 1.8.5**
>
> Previously the outermost atomic block couldn't be declared with
> `savepoint=False` when autocommit was turned off.

> **Pertimbangan penampilan**
>
> Open transactions have a performance cost for your database server. To
> minimize this overhead, keep your transactions as short as possible. This
> is especially important if you're using [`atomic()`](#django.db.transaction.atomic) in long-running
> processes, outside of Django's request / response cycle.

## Penyerahan otomatis

### Kenapa Django menggunakan penyerahan otomatis

Dalam standar SQL, setiap permintaan SQL memulai sebuah transaksi, meskipun satu sudah aktif. Transaksi tersebut harus secara eksplisit diserahkan dan digulung kembali.

Ini tidak selalu mudah untuk pengembang aplikasi. Untuk meredakan masalah ini, kebanyakan basisdata menyediakan sebuah suasana penyerahan otomatis. Ketika penyerahan otomatis dinayalan dan tidak ada transaksi aktif, setiap permintaan SQL dibungkus dalam transaksinya sendiri. Dengan kata lain, bukan hanya melakukan setiap permintaan tersebut mulai sebuah transaksi, tetapi transaksi juga mendapatkan otomatis diserahkan atau digulung kembali, tergandunt pada apakah permintaan berhasil.

[**PEP 249**](https://peps.python.org/pep-0249/), the Python Database API Specification v2.0, requires autocommit to
be initially turned off. Django overrides this default and turns autocommit
on.

Untuk menghindari ini, anda dapat  [menonaktifkan pengelolaan transaksi](#deactivate-transaction-management), tetapi itu sangat tidak dianjurkan.

### Menonaktifkan pengelolaan transaksi

You can totally disable Django's transaction management for a given database
by setting [`AUTOCOMMIT`](/id/1.9/ref/settings/#std-setting-DATABASE-AUTOCOMMIT) to `False` in its
configuration. If you do this, Django won't enable autocommit, and won't
perform any commits. You'll get the regular behavior of the underlying
database library.

Ini membutuhkan anda utnuk menyerahkan secara eksplisit setiap transaksi, bahkan yang dimulai oleh Django atau oleh pustaka pihak ketiga. Jadi, ini adalah penggunaan terbaik dalam keadaan dimana anda ingin menjalankan middleware pengendalian transaksi milik anda atau melakukan sesuatu yang sangat aneh.

## Melakukan tindakan setelah penyerahan

> **New in Django 1.9**

Terkadang anda butuh melakukan sebuah tindakan terkait pada transaksi basisdata saat ini, tetapi hanya jika transaksi berhasil diserahkan. Contoh mungkin termasuk tugas [Celery](http://www.celeryproject.org/), sebuah pemberitahuan surel, atau penghapusan tembolok

Django menyediakan fungsi [`on_commit()`](#django.db.transaction.on_commit) untuk mendaftarkan fungsi panggil kembali yang harusnya dijalankan setelah transaksi berhasil diserahkan:

#### `on_commit(func, using=None)`

Lewati fungsi apapun (yang tidak mengambil argumen) ke [`on_commit()`](#django.db.transaction.on_commit):

```
from django.db import transaction

def do_something():
    pass  # send a mail, invalidate a cache, fire off a Celery task, etc.

transaction.on_commit(do_something)
```

Anda dapat juga membungkus fungsi anda dalam lambda:

```
transaction.on_commit(lambda: some_celery_task.delay('arg1'))
```

Fungsi anda lewati akan dipanggil segera setelah hipotetis penulisan basisdata dibuat dimana `on_commit()` dipanggil akan berhasil diserahkan.

Jika anda memanggil `on_commit()` selagi tidak ada sebiah transaksi aktif, panggil kembali akan dijalankan segera.

Jika hipotetis penulisan basisdata itu bukannya digulung kembali (khususnya ketika sebuah pengecualian tidak tertangani dimunculkan dalam sebuah blok [`atomic()`](#django.db.transaction.atomic)), fungsi anda akan disingkirkan dan tidak pernah dipanggil.

### Savepoint

Titik simpan (yaitu blok  [`atomic()`](#django.db.transaction.atomic) bersarang) ditangani dengan benar. Yaitu, sebuah pemganggilan [`on_commit()`](#django.db.transaction.on_commit) terdaftar setelah sebuah titik simpan (dalam blok  [`atomic()`](#django.db.transaction.atomic) bersarang) akan dipanggil setelah transaksi paling luar diserahkan, tetapi tidak jika digulung kembali ke titik simpan tersebut atau titik simpan sebelumnya yang muncul selama transaksi:

```
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
```

Pada sisi lain, ketika sebuah titik simpan digulung kembali (karena sebuah pengecualian telah dimunculkan), bagian dalam dapat dipanggil tidak akan dipanggil:

```
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()
```

### Urutan pelaksanaan

On-commit functions for a given transaction are executed in the order they were
registered.

### Penanganan pengecualian

If one on-commit function within a given transaction raises an uncaught
exception, no later registered functions in that same transaction will run.
This is, of course, the same behavior as if you'd executed the functions
sequentially yourself without [`on_commit()`](#django.db.transaction.on_commit).

### Waktu pelaksanaan

Gulungan kembali anda dijalankan *setelah* penyerahan berhasil, jadi sebuah kegagalan dalam gulung kembali tidak akan menyebabkan transaksi di gulung kembali. Mereka dijalankan kondisional atas transaksi berhasil, tetapi mereka bukan *bagian* dari transaksi. Untuk penggunaan kasus dimaksud (pemberitahuan surat, tugas Celery, dll.), ini harus baik-baik saja. Jika tidak (jika tindakan mengikuti anda juga gawat dimana kegagalan itu harus berarti kegagalan dari transaksi itu sendiri), lalu anda tidak ingin menggunakan hubungan  [`on_commit()`](#django.db.transaction.on_commit). Sebagai gantinya, anda ingin [two-phase commit](https://en.wikipedia.org/wiki/Two-phase_commit_protocol) seperti [psycopg Two-Phase Commit protocol support](http://initd.org/psycopg/docs/usage.html#tpc) dan [optional Two-Phase Commit Extensions in the Python DB-API specification](https://www.python.org/dev/peps/pep-0249/#optional-two-phase-commit-extensions).

Callbacks are not run until autocommit is restored on the connection following
the commit (because otherwise any queries done in a callback would open an
implicit transaction, preventing the connection from going back into autocommit
mode).

When in autocommit mode and outside of an [`atomic()`](#django.db.transaction.atomic) block, the function
will run immediately, not on commit.

On-commit functions only work with [autocommit mode](#managing-autocommit)
and the [`atomic()`](#django.db.transaction.atomic) (or [`ATOMIC_REQUESTS`](/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS)) transaction API. Calling [`on_commit()`](#django.db.transaction.on_commit) when
autocommit is disabled and you are not within an atomic block will result in an
error.

### Use in tests

Django's [`TestCase`](/id/1.9/topics/testing/tools/#django.test.TestCase) class wraps each test in a transaction
and rolls back that transaction after each test, in order to provide test
isolation. This means that no transaction is ever actually committed, thus your
[`on_commit()`](#django.db.transaction.on_commit) callbacks will never be run. If you need to test the results
of an [`on_commit()`](#django.db.transaction.on_commit) callback, use a
[`TransactionTestCase`](/id/1.9/topics/testing/tools/#django.test.TransactionTestCase) instead.

### Why no rollback hook?

A rollback hook is harder to implement robustly than a commit hook, since a
variety of things can cause an implicit rollback.

For instance, if your database connection is dropped because your process was
killed without a chance to shut down gracefully, your rollback hook will never
run.

The solution is simple: instead of doing something during the atomic block
(transaction) and then undoing it if the transaction fails, use
[`on_commit()`](#django.db.transaction.on_commit) to delay doing it in the first place until after the
transaction succeeds. It’s a lot easier to undo something you never did in the
first place!

## Low-level APIs

> **Warning**
>
> Always prefer [`atomic()`](#django.db.transaction.atomic) if possible at all. It accounts for the
> idiosyncrasies of each database and prevents invalid operations.
>
> The low level APIs are only useful if you're implementing your own
> transaction management.

### Penyerahan otomatis

Django provides a straightforward API in the [`django.db.transaction`](#module-django.db.transaction)
module to manage the autocommit state of each database connection.

#### `get_autocommit(using=None)`

#### `set_autocommit(autocommit, using=None)`

These functions take a `using` argument which should be the name of a
database. If it isn't provided, Django uses the `"default"` database.

Autocommit is initially turned on. If you turn it off, it's your
responsibility to restore it.

Once you turn autocommit off, you get the default behavior of your database
adapter, and Django won't help you. Although that behavior is specified in
[**PEP 249**](https://peps.python.org/pep-0249/), implementations of adapters aren't always consistent with one
another. Review the documentation of the adapter you're using carefully.

You must ensure that no transaction is active, usually by issuing a
[`commit()`](#django.db.transaction.commit) or a [`rollback()`](#django.db.transaction.rollback), before turning autocommit back on.

Django will refuse to turn autocommit off when an [`atomic()`](#django.db.transaction.atomic) block is
active, because that would break atomicity.

### Transaksi

A transaction is an atomic set of database queries. Even if your program
crashes, the database guarantees that either all the changes will be applied,
or none of them.

Django doesn't provide an API to start a transaction. The expected way to
start a transaction is to disable autocommit with [`set_autocommit()`](#django.db.transaction.set_autocommit).

Once you're in a transaction, you can choose either to apply the changes
you've performed until this point with [`commit()`](#django.db.transaction.commit), or to cancel them with
[`rollback()`](#django.db.transaction.rollback). These functions are defined in [`django.db.transaction`](#module-django.db.transaction).

#### `commit(using=None)`

#### `rollback(using=None)`

These functions take a `using` argument which should be the name of a
database. If it isn't provided, Django uses the `"default"` database.

Django will refuse to commit or to rollback when an [`atomic()`](#django.db.transaction.atomic) block is
active, because that would break atomicity.

### Savepoint

A savepoint is a marker within a transaction that enables you to roll back
part of a transaction, rather than the full transaction. Savepoints are
available with the SQLite (≥ 3.6.8), PostgreSQL, Oracle and MySQL (when using
the InnoDB storage engine) backends. Other backends provide the savepoint
functions, but they're empty operations -- they don't actually do anything.

Savepoints aren't especially useful if you are using autocommit, the default
behavior of Django. However, once you open a transaction with [`atomic()`](#django.db.transaction.atomic),
you build up a series of database operations awaiting a commit or rollback. If
you issue a rollback, the entire transaction is rolled back. Savepoints
provide the ability to perform a fine-grained rollback, rather than the full
rollback that would be performed by `transaction.rollback()`.

When the [`atomic()`](#django.db.transaction.atomic) decorator is nested, it creates a savepoint to allow
partial commit or rollback. You're strongly encouraged to use [`atomic()`](#django.db.transaction.atomic)
rather than the functions described below, but they're still part of the
public API, and there's no plan to deprecate them.

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.

Savepoints are controlled by three functions in [`django.db.transaction`](#module-django.db.transaction):

#### `savepoint(using=None)`

Creates a new savepoint. This marks a point in the transaction that is
known to be in a "good" state. Returns the savepoint ID (`sid`).

#### `savepoint_commit(sid, using=None)`

Releases savepoint `sid`. The changes performed since the savepoint was
created become part of the transaction.

#### `savepoint_rollback(sid, using=None)`

Rolls back the transaction to savepoint `sid`.

These functions do nothing if savepoints aren't supported or if the database
is in autocommit mode.

In addition, there's a utility function:

#### `clean_savepoints(using=None)`

Resets the counter used to generate unique savepoint IDs.

The following example demonstrates the use of savepoints:

```
from django.db import transaction

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

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

    sid = transaction.savepoint()

    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 may be used to recover from a database error by performing a partial
rollback. If you're doing this inside an [`atomic()`](#django.db.transaction.atomic) block, the entire block
will still be rolled back, because it doesn't know you've handled the situation
at a lower level! To prevent this, you can control the rollback behavior with
the following functions.

#### `get_rollback(using=None)`

#### `set_rollback(rollback, using=None)`

Setting the rollback flag to `True` forces a rollback when exiting the
innermost atomic block. This may be useful to trigger a rollback without
raising an exception.

Setting it to `False` prevents such a rollback. Before doing that, make sure
you've rolled back the transaction to a known-good savepoint within the current
atomic block! Otherwise you're breaking atomicity and data corruption may
occur.

## Database-specific notes

### Savepoint di SQLite

While SQLite ≥ 3.6.8 supports savepoints, a flaw in the design of the
[`sqlite3`](https://docs.python.org/3/library/sqlite3.html#module-sqlite3) module makes them hardly usable.

When autocommit is enabled, savepoints don't make sense. When it's disabled,
[`sqlite3`](https://docs.python.org/3/library/sqlite3.html#module-sqlite3) commits implicitly before savepoint statements. (In fact, it
commits before any statement other than `SELECT`, `INSERT`, `UPDATE`,
`DELETE` and `REPLACE`.) This bug has two consequences:

- The low level APIs for savepoints are only usable inside a transaction ie.
  inside an [`atomic()`](#django.db.transaction.atomic) block.
- It's impossible to use [`atomic()`](#django.db.transaction.atomic) when autocommit is turned off.

### Transaksi di MySQL

If you're using MySQL, your tables may or may not support transactions; it
depends on your MySQL version and the table types you're using. (By
"table types," we mean something like "InnoDB" or "MyISAM".) MySQL transaction
peculiarities are outside the scope of this article, but the MySQL site has
[information on MySQL transactions](https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-transactions.html).

If your MySQL setup does *not* support transactions, then Django will always
function in autocommit mode: statements will be executed and committed as soon
as they're called. If your MySQL setup *does* support transactions, Django
will handle transactions as explained in this document.

### Penanganan pengecualian dalam transaksi PostgreSQL

> **Note**
>
> This section is relevant only if you're implementing your own transaction
> management. This problem cannot occur in Django's default mode and
> [`atomic()`](#django.db.transaction.atomic) handles it automatically.

Inside a transaction, when a call to a PostgreSQL cursor raises an exception
(typically `IntegrityError`), all subsequent SQL in the same transaction
will fail with the error "current transaction is aborted, queries ignored
until end of transaction block". While simple use of `save()` is unlikely
to raise an exception in PostgreSQL, there are more advanced usage patterns
which might, such as saving objects with unique fields, saving using the
force\_insert/force\_update flag, or invoking custom SQL.

There are several ways to recover from this sort of error.

#### Gulung kembali transaksi

The first option is to roll back the entire transaction. For example:

```
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
```

Calling `transaction.rollback()` rolls back the entire transaction. Any
uncommitted database operations will be lost. In this example, the changes
made by `a.save()` would be lost, even though that operation raised no error
itself.

#### Savepoint rollback

You can use [savepoints](#topics-db-transactions-savepoints) to control
the extent of a rollback. Before performing a database operation that could
fail, you can set or update the savepoint; that way, if the operation fails,
you can roll back the single offending operation, rather than the entire
transaction. For example:

```
a.save() # Succeeds, and never undone by savepoint rollback
sid = transaction.savepoint()
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
```

In this example, `a.save()` will not be undone in the case where
`b.save()` raises an exception.
