{"title":"Transaksi basisdata","version":"1.9","locale":"id","docname":"topics/db/transactions","url":"/id/1.9/topics/db/transactions/","canonical":"https://djangodocs.dev/id/1.9/topics/db/transactions/","summary":"Django memberikan anda sedikit cara mengendalikan bagaimana transaksi basisdata dikelola.","html":"<span id=\"database-transactions\"></span><h1>Transaksi basisdata<a class=\"heading-anchor\" href=\"#module-django.db.transaction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django memberikan anda sedikit cara mengendalikan bagaimana transaksi basisdata dikelola.</p>\n<section id=\"managing-database-transactions\">\n<h2>Mengelola transaksi basisdata<a class=\"heading-anchor\" href=\"#managing-database-transactions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"django-s-default-transaction-behavior\">\n<h3>Kebiasaan transaksi awal Django<a class=\"heading-anchor\" href=\"#django-s-default-transaction-behavior\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Kebiasaan awal Django adalah menjalankan suasana penyeraahn otomatis. Setiap query segera diserahkan ke basisdata, meskipun transaksi adalah aktif. <a class=\"reference internal\" href=\"#autocommit-details\"><span class=\"std std-ref\">Lihat dibawah ini untuk rincian</span></a>.</p>\n<p>Django menggunakan transaksi atau titiksimpan otomatis untuk menjamin kesatuan dari operasi ORM yang membutuhkan banyak query, khususnya query <a class=\"reference internal\" href=\"/id/1.9/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">delete()</span></a> dan <a class=\"reference internal\" href=\"/id/1.9/topics/db/queries/#topics-db-queries-update\"><span class=\"std std-ref\">update()</span></a>.</p>\n<p>Django's <a class=\"reference internal\" href=\"/id/1.9/topics/testing/tools/#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\">TestCase</code></a> class also wraps each test in a\ntransaction for performance reasons.</p>\n</section>\n<section id=\"tying-transactions-to-http-requests\">\n<span id=\"id1\"></span><h3>Tying transactions to HTTP requests<a class=\"heading-anchor\" href=\"#tying-transactions-to-http-requests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Cara umum untuk menangani transaksi di jaringan adalah membungkus setiap permintaan di transaksi. Setel <a class=\"reference internal\" href=\"/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\">ATOMIC_REQUESTS</code></a> ke <code class=\"docutils literal notranslate\">True</code> di konfigurasi dari setiap basisdata untuk anda ingin adakan kebiasaan ini.</p>\n<p>It works like this. Before calling a view function, Django starts a\ntransaction. If the response is produced without problems, Django commits the\ntransaction. If the view produces an exception, Django rolls back the\ntransaction.</p>\n<p>You may perform subtransactions using savepoints in your view code, typically\nwith the <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> context manager. However, at the end of the view,\neither all or none of the changes will be committed.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Peringatan</p>\n<p>While the simplicity of this transaction model is appealing, it also makes it\ninefficient when traffic increases. Opening a transaction for every view has\nsome overhead. The impact on performance depends on the query patterns of your\napplication and on how well your database handles locking.</p>\n</aside>\n<aside class=\"admonition-per-request-transactions-and-streaming-responses admonition\" role=\"note\">\n<p class=\"admonition-title\">Per-request transactions and streaming responses</p>\n<p>When a view returns a <a class=\"reference internal\" href=\"/id/1.9/ref/request-response/#django.http.StreamingHttpResponse\" title=\"django.http.StreamingHttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">StreamingHttpResponse</code></a>, reading\nthe contents of the response will often execute code to generate the\ncontent. Since the view has already returned, such code runs outside of\nthe transaction.</p>\n<p>Generally speaking, it isn't advisable to write to the database while\ngenerating a streaming response, since there's no sensible way to handle\nerrors after starting to send the response.</p>\n</aside>\n<p>In practice, this feature simply wraps every view function in the <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a>\ndecorator described below.</p>\n<p>Note that only the execution of your view is enclosed in the transactions.\nMiddleware runs outside of the transaction, and so does the rendering of\ntemplate responses.</p>\n<p>When <a class=\"reference internal\" href=\"/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\">ATOMIC_REQUESTS</code></a> is enabled, it's\nstill possible to prevent views from running in a transaction.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.non_atomic_requests\">\n<span class=\"sig-name descname\">non_atomic_requests</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.non_atomic_requests\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>This decorator will negate the effect of <a class=\"reference internal\" href=\"/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\">ATOMIC_REQUESTS</code></a> for a given view:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span>non_atomic_requests\n<span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    do_stuff<span class=\"p\">()</span>\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span>non_atomic_requests<span class=\"p\">(</span>using<span class=\"o\">=</span><span class=\"s1\">&#39;other&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">my_other_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    do_stuff_on_the_other_database<span class=\"p\">()</span>\n</code></pre></div>\n<p>It only works if it's applied to the view itself.</p>\n</dd></dl>\n\n</section>\n<section id=\"controlling-transactions-explicitly\">\n<h3>Mengendalikan transaksi secara eksplisit<a class=\"heading-anchor\" href=\"#controlling-transactions-explicitly\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django provides a single API to control database transactions.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.atomic\">\n<span class=\"sig-name descname\">atomic</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">savepoint<span class=\"o\">=</span><span class=\"default_value\">True</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.atomic\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Atomicity is the defining property of database transactions. <code class=\"docutils literal notranslate\">atomic</code>\nallows us to create a block of code within which the atomicity on the\ndatabase is guaranteed. If the block of code is successfully completed, the\nchanges are committed to the database. If there is an exception, the\nchanges are rolled back.</p>\n<p><code class=\"docutils literal notranslate\">atomic</code> blocks can be nested. In this case, when an inner block\ncompletes successfully, its effects can still be rolled back if an\nexception is raised in the outer block at a later point.</p>\n<p><code class=\"docutils literal notranslate\">atomic</code> is usable both as a <a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-decorator\" title=\"(di Python v3.14)\"><span class=\"xref std std-term\">decorator</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span>atomic\n<span class=\"k\">def</span> <span class=\"nf\">viewfunc</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"c1\"># This code executes inside a transaction.</span>\n    do_stuff<span class=\"p\">()</span>\n</code></pre></div>\n<p>dan sebagai <a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-context-manager\" title=\"(di Python v3.14)\"><span class=\"xref std std-term\">context manager</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"k\">def</span> <span class=\"nf\">viewfunc</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"c1\"># This code executes in autocommit mode (Django&#39;s default).</span>\n    do_stuff<span class=\"p\">()</span>\n\n    <span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>\n        <span class=\"c1\"># This code executes inside a transaction.</span>\n        do_more_stuff<span class=\"p\">()</span>\n</code></pre></div>\n<p>Wrapping <code class=\"docutils literal notranslate\">atomic</code> in a try/except block allows for natural handling of\nintegrity errors:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> IntegrityError<span class=\"p\">,</span> transaction\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span>atomic\n<span class=\"k\">def</span> <span class=\"nf\">viewfunc</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    create_parent<span class=\"p\">()</span>\n\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>\n            generate_relationships<span class=\"p\">()</span>\n    <span class=\"k\">except</span> IntegrityError<span class=\"p\">:</span>\n        handle_exception<span class=\"p\">()</span>\n\n    add_children<span class=\"p\">()</span>\n</code></pre></div>\n<p>In this example, even if <code class=\"docutils literal notranslate\">generate_relationships()</code> causes a database\nerror by breaking an integrity constraint, you can execute queries in\n<code class=\"docutils literal notranslate\">add_children()</code>, and the changes from <code class=\"docutils literal notranslate\">create_parent()</code> are still\nthere. Note that any operations attempted in <code class=\"docutils literal notranslate\">generate_relationships()</code>\nwill already have been rolled back safely when <code class=\"docutils literal notranslate\">handle_exception()</code> is\ncalled, so the exception handler can also operate on the database if\nnecessary.</p>\n<aside class=\"admonition-avoid-catching-exceptions-inside-atomic admonition\" role=\"note\">\n<p class=\"admonition-title\">Avoid catching exceptions inside <code class=\"docutils literal notranslate\">atomic</code>!</p>\n<p>When exiting an <code class=\"docutils literal notranslate\">atomic</code> block, Django looks at whether it's exited\nnormally or with an exception to determine whether to commit or roll\nback. If you catch and handle exceptions inside an <code class=\"docutils literal notranslate\">atomic</code> block,\nyou may hide from Django the fact that a problem has happened. This\ncan result in unexpected behavior.</p>\n<p>This is mostly a concern for <a class=\"reference internal\" href=\"/id/1.9/ref/exceptions/#django.db.DatabaseError\" title=\"django.db.DatabaseError\"><code class=\"xref py py-exc docutils literal notranslate\">DatabaseError</code></a> and its\nsubclasses such as <a class=\"reference internal\" href=\"/id/1.9/ref/exceptions/#django.db.IntegrityError\" title=\"django.db.IntegrityError\"><code class=\"xref py py-exc docutils literal notranslate\">IntegrityError</code></a>. After such an\nerror, the transaction is broken and Django will perform a rollback at\nthe end of the <code class=\"docutils literal notranslate\">atomic</code> block. If you attempt to run database\nqueries before the rollback happens, Django will raise a\n<a class=\"reference internal\" href=\"/id/1.9/ref/exceptions/#django.db.transaction.TransactionManagementError\" title=\"django.db.transaction.TransactionManagementError\"><code class=\"xref py py-class docutils literal notranslate\">TransactionManagementError</code></a>. You may\nalso encounter this behavior when an ORM-related signal handler raises\nan exception.</p>\n<p>The correct way to catch database errors is around an <code class=\"docutils literal notranslate\">atomic</code> block\nas shown above. If necessary, add an extra <code class=\"docutils literal notranslate\">atomic</code> block for this\npurpose. This pattern has another advantage: it delimits explicitly\nwhich operations will be rolled back if an exception occurs.</p>\n<p>If you catch exceptions raised by raw SQL queries, Django's behavior\nis unspecified and database-dependent.</p>\n</aside>\n<p>In order to guarantee atomicity, <code class=\"docutils literal notranslate\">atomic</code> disables some APIs. Attempting\nto commit, roll back, or change the autocommit state of the database\nconnection within an <code class=\"docutils literal notranslate\">atomic</code> block will raise an exception.</p>\n<p><code class=\"docutils literal notranslate\">atomic</code> takes a <code class=\"docutils literal notranslate\">using</code> argument which should be the name of a\ndatabase. If this argument isn't provided, Django uses the <code class=\"docutils literal notranslate\">&quot;default&quot;</code>\ndatabase.</p>\n<p>Dibawah tenda, kode pengelolaan transaksi Django:</p>\n<ul class=\"simple\">\n<li><p>membuka sebuah transaksi ketika memasukkan blok <code class=\"docutils literal notranslate\">atomic</code> paling luar;</p></li>\n<li><p>membuat titiksimpan ketika memasukkan blok <code class=\"docutils literal notranslate\">atomic</code> paling dalam;</p></li>\n<li><p>melepaskan atau digulung kembali ke titik simpan ketika keluar blok paling dalam;</p></li>\n<li><p>menyerahkan atau gulung kembali transaksi ketika keluar blok paling luar</p></li>\n</ul>\n<p>Anda dapat meniadakan pembuatan dari titik simpan untuk blok paling dalam dengan mengatur argumen <code class=\"docutils literal notranslate\">savepoint</code> ke <code class=\"docutils literal notranslate\">False</code>. 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.</p>\n<p>Anda dapat menggunakan <code class=\"docutils literal notranslate\">atomic</code> ketika penyerahan otomatis dimatikan. Itu akan hanya menggunakan titik simpan, bahkan untuk blok paling luar.</p>\n<aside class=\"version-note version-changed\" data-version=\"1.8.5\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 1.8.5</p><p>Previously the outermost atomic block couldn't be declared with\n<code class=\"docutils literal notranslate\">savepoint=False</code> when autocommit was turned off.</p>\n</aside>\n</dd></dl>\n\n<aside class=\"admonition-performance-considerations admonition\" role=\"note\">\n<p class=\"admonition-title\">Pertimbangan penampilan</p>\n<p>Open transactions have a performance cost for your database server. To\nminimize this overhead, keep your transactions as short as possible. This\nis especially important if you're using <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> in long-running\nprocesses, outside of Django's request / response cycle.</p>\n</aside>\n</section>\n</section>\n<section id=\"autocommit\">\n<h2>Penyerahan otomatis<a class=\"heading-anchor\" href=\"#autocommit\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"why-django-uses-autocommit\">\n<span id=\"autocommit-details\"></span><h3>Kenapa Django menggunakan penyerahan otomatis<a class=\"heading-anchor\" href=\"#why-django-uses-autocommit\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Dalam standar SQL, setiap permintaan SQL memulai sebuah transaksi, meskipun satu sudah aktif. Transaksi tersebut harus secara eksplisit diserahkan dan digulung kembali.</p>\n<p>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.</p>\n<p><span class=\"target\" id=\"index-0\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0249/\"><strong>PEP 249</strong></a>, the Python Database API Specification v2.0, requires autocommit to\nbe initially turned off. Django overrides this default and turns autocommit\non.</p>\n<p>Untuk menghindari ini, anda dapat  <a class=\"reference internal\" href=\"#deactivate-transaction-management\"><span class=\"std std-ref\">menonaktifkan pengelolaan transaksi</span></a>, tetapi itu sangat tidak dianjurkan.</p>\n</section>\n<section id=\"deactivating-transaction-management\">\n<span id=\"deactivate-transaction-management\"></span><h3>Menonaktifkan pengelolaan transaksi<a class=\"heading-anchor\" href=\"#deactivating-transaction-management\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>You can totally disable Django's transaction management for a given database\nby setting <a class=\"reference internal\" href=\"/id/1.9/ref/settings/#std-setting-DATABASE-AUTOCOMMIT\"><code class=\"xref std std-setting docutils literal notranslate\">AUTOCOMMIT</code></a> to <code class=\"docutils literal notranslate\">False</code> in its\nconfiguration. If you do this, Django won't enable autocommit, and won't\nperform any commits. You'll get the regular behavior of the underlying\ndatabase library.</p>\n<p>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.</p>\n</section>\n</section>\n<section id=\"performing-actions-after-commit\">\n<h2>Melakukan tindakan setelah penyerahan<a class=\"heading-anchor\" href=\"#performing-actions-after-commit\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"version-note version-added\" data-version=\"1.9\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.9</p></aside>\n<p>Terkadang anda butuh melakukan sebuah tindakan terkait pada transaksi basisdata saat ini, tetapi hanya jika transaksi berhasil diserahkan. Contoh mungkin termasuk tugas <a class=\"reference external\" href=\"http://www.celeryproject.org/\">Celery</a>, sebuah pemberitahuan surel, atau penghapusan tembolok</p>\n<p>Django menyediakan fungsi <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> untuk mendaftarkan fungsi panggil kembali yang harusnya dijalankan setelah transaksi berhasil diserahkan:</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.on_commit\">\n<span class=\"sig-name descname\">on_commit</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">func</em>, <em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.on_commit\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Lewati fungsi apapun (yang tidak mengambil argumen) ke <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"k\">def</span> <span class=\"nf\">do_something</span><span class=\"p\">():</span>\n    <span class=\"k\">pass</span>  <span class=\"c1\"># send a mail, invalidate a cache, fire off a Celery task, etc.</span>\n\ntransaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span>do_something<span class=\"p\">)</span>\n</code></pre></div>\n<p>Anda dapat juga membungkus fungsi anda dalam lambda:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>transaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span><span class=\"k\">lambda</span><span class=\"p\">:</span> some_celery_task<span class=\"o\">.</span>delay<span class=\"p\">(</span><span class=\"s1\">&#39;arg1&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Fungsi anda lewati akan dipanggil segera setelah hipotetis penulisan basisdata dibuat dimana <code class=\"docutils literal notranslate\">on_commit()</code> dipanggil akan berhasil diserahkan.</p>\n<p>Jika anda memanggil <code class=\"docutils literal notranslate\">on_commit()</code> selagi tidak ada sebiah transaksi aktif, panggil kembali akan dijalankan segera.</p>\n<p>Jika hipotetis penulisan basisdata itu bukannya digulung kembali (khususnya ketika sebuah pengecualian tidak tertangani dimunculkan dalam sebuah blok <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a>), fungsi anda akan disingkirkan dan tidak pernah dipanggil.</p>\n<section id=\"savepoints\">\n<h3>Savepoint<a class=\"heading-anchor\" href=\"#savepoints\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Titik simpan (yaitu blok  <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> bersarang) ditangani dengan benar. Yaitu, sebuah pemganggilan <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> terdaftar setelah sebuah titik simpan (dalam blok  <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> 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:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>  <span class=\"c1\"># Outer atomic, start a new transaction</span>\n    transaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span>foo<span class=\"p\">)</span>\n\n    <span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>  <span class=\"c1\"># Inner atomic block, create a savepoint</span>\n        transaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span>bar<span class=\"p\">)</span>\n\n<span class=\"c1\"># foo() and then bar() will be called when leaving the outermost block</span>\n</code></pre></div>\n<p>Pada sisi lain, ketika sebuah titik simpan digulung kembali (karena sebuah pengecualian telah dimunculkan), bagian dalam dapat dipanggil tidak akan dipanggil:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>  <span class=\"c1\"># Outer atomic, start a new transaction</span>\n    transaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span>foo<span class=\"p\">)</span>\n\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>  <span class=\"c1\"># Inner atomic block, create a savepoint</span>\n            transaction<span class=\"o\">.</span>on_commit<span class=\"p\">(</span>bar<span class=\"p\">)</span>\n            <span class=\"k\">raise</span> SomeError<span class=\"p\">()</span>  <span class=\"c1\"># Raising an exception - abort the savepoint</span>\n    <span class=\"k\">except</span> SomeError<span class=\"p\">:</span>\n        <span class=\"k\">pass</span>\n\n<span class=\"c1\"># foo() will be called, but not bar()</span>\n</code></pre></div>\n</section>\n<section id=\"order-of-execution\">\n<h3>Urutan pelaksanaan<a class=\"heading-anchor\" href=\"#order-of-execution\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>On-commit functions for a given transaction are executed in the order they were\nregistered.</p>\n</section>\n<section id=\"exception-handling\">\n<h3>Penanganan pengecualian<a class=\"heading-anchor\" href=\"#exception-handling\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If one on-commit function within a given transaction raises an uncaught\nexception, no later registered functions in that same transaction will run.\nThis is, of course, the same behavior as if you'd executed the functions\nsequentially yourself without <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a>.</p>\n</section>\n<section id=\"timing-of-execution\">\n<h3>Waktu pelaksanaan<a class=\"heading-anchor\" href=\"#timing-of-execution\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Gulungan kembali anda dijalankan <em>setelah</em> penyerahan berhasil, jadi sebuah kegagalan dalam gulung kembali tidak akan menyebabkan transaksi di gulung kembali. Mereka dijalankan kondisional atas transaksi berhasil, tetapi mereka bukan <em>bagian</em> 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  <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a>. Sebagai gantinya, anda ingin <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Two-phase_commit_protocol\">two-phase commit</a> seperti <a class=\"reference external\" href=\"http://initd.org/psycopg/docs/usage.html#tpc\">psycopg Two-Phase Commit protocol support</a> dan <a class=\"reference external\" href=\"https://www.python.org/dev/peps/pep-0249/#optional-two-phase-commit-extensions\">optional Two-Phase Commit Extensions in the Python DB-API specification</a>.</p>\n<p>Callbacks are not run until autocommit is restored on the connection following\nthe commit (because otherwise any queries done in a callback would open an\nimplicit transaction, preventing the connection from going back into autocommit\nmode).</p>\n<p>When in autocommit mode and outside of an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> block, the function\nwill run immediately, not on commit.</p>\n<p>On-commit functions only work with <a class=\"reference internal\" href=\"#managing-autocommit\"><span class=\"std std-ref\">autocommit mode</span></a>\nand the <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> (or <a class=\"reference internal\" href=\"/id/1.9/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\">ATOMIC_REQUESTS</code></a>) transaction API. Calling <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> when\nautocommit is disabled and you are not within an atomic block will result in an\nerror.</p>\n</section>\n<section id=\"use-in-tests\">\n<h3>Use in tests<a class=\"heading-anchor\" href=\"#use-in-tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django's <a class=\"reference internal\" href=\"/id/1.9/topics/testing/tools/#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\">TestCase</code></a> class wraps each test in a transaction\nand rolls back that transaction after each test, in order to provide test\nisolation. This means that no transaction is ever actually committed, thus your\n<a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> callbacks will never be run. If you need to test the results\nof an <a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> callback, use a\n<a class=\"reference internal\" href=\"/id/1.9/topics/testing/tools/#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\">TransactionTestCase</code></a> instead.</p>\n</section>\n<section id=\"why-no-rollback-hook\">\n<h3>Why no rollback hook?<a class=\"heading-anchor\" href=\"#why-no-rollback-hook\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A rollback hook is harder to implement robustly than a commit hook, since a\nvariety of things can cause an implicit rollback.</p>\n<p>For instance, if your database connection is dropped because your process was\nkilled without a chance to shut down gracefully, your rollback hook will never\nrun.</p>\n<p>The solution is simple: instead of doing something during the atomic block\n(transaction) and then undoing it if the transaction fails, use\n<a class=\"reference internal\" href=\"#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\">on_commit()</code></a> to delay doing it in the first place until after the\ntransaction succeeds. It’s a lot easier to undo something you never did in the\nfirst place!</p>\n</section>\n</section>\n<section id=\"low-level-apis\">\n<h2>Low-level APIs<a class=\"heading-anchor\" href=\"#low-level-apis\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Peringatan</p>\n<p>Always prefer <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> if possible at all. It accounts for the\nidiosyncrasies of each database and prevents invalid operations.</p>\n<p>The low level APIs are only useful if you're implementing your own\ntransaction management.</p>\n</aside>\n<section id=\"managing-autocommit\">\n<span id=\"id2\"></span><h3>Penyerahan otomatis<a class=\"heading-anchor\" href=\"#managing-autocommit\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django provides a straightforward API in the <a class=\"reference internal\" href=\"#module-django.db.transaction\" title=\"django.db.transaction\"><code class=\"xref py py-mod docutils literal notranslate\">django.db.transaction</code></a>\nmodule to manage the autocommit state of each database connection.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.get_autocommit\">\n<span class=\"sig-name descname\">get_autocommit</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.get_autocommit\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.set_autocommit\">\n<span class=\"sig-name descname\">set_autocommit</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">autocommit</em>, <em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.set_autocommit\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>These functions take a <code class=\"docutils literal notranslate\">using</code> argument which should be the name of a\ndatabase. If it isn't provided, Django uses the <code class=\"docutils literal notranslate\">&quot;default&quot;</code> database.</p>\n<p>Autocommit is initially turned on. If you turn it off, it's your\nresponsibility to restore it.</p>\n<p>Once you turn autocommit off, you get the default behavior of your database\nadapter, and Django won't help you. Although that behavior is specified in\n<span class=\"target\" id=\"index-1\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0249/\"><strong>PEP 249</strong></a>, implementations of adapters aren't always consistent with one\nanother. Review the documentation of the adapter you're using carefully.</p>\n<p>You must ensure that no transaction is active, usually by issuing a\n<a class=\"reference internal\" href=\"#django.db.transaction.commit\" title=\"django.db.transaction.commit\"><code class=\"xref py py-func docutils literal notranslate\">commit()</code></a> or a <a class=\"reference internal\" href=\"#django.db.transaction.rollback\" title=\"django.db.transaction.rollback\"><code class=\"xref py py-func docutils literal notranslate\">rollback()</code></a>, before turning autocommit back on.</p>\n<p>Django will refuse to turn autocommit off when an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> block is\nactive, because that would break atomicity.</p>\n</section>\n<section id=\"transactions\">\n<h3>Transaksi<a class=\"heading-anchor\" href=\"#transactions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A transaction is an atomic set of database queries. Even if your program\ncrashes, the database guarantees that either all the changes will be applied,\nor none of them.</p>\n<p>Django doesn't provide an API to start a transaction. The expected way to\nstart a transaction is to disable autocommit with <a class=\"reference internal\" href=\"#django.db.transaction.set_autocommit\" title=\"django.db.transaction.set_autocommit\"><code class=\"xref py py-func docutils literal notranslate\">set_autocommit()</code></a>.</p>\n<p>Once you're in a transaction, you can choose either to apply the changes\nyou've performed until this point with <a class=\"reference internal\" href=\"#django.db.transaction.commit\" title=\"django.db.transaction.commit\"><code class=\"xref py py-func docutils literal notranslate\">commit()</code></a>, or to cancel them with\n<a class=\"reference internal\" href=\"#django.db.transaction.rollback\" title=\"django.db.transaction.rollback\"><code class=\"xref py py-func docutils literal notranslate\">rollback()</code></a>. These functions are defined in <a class=\"reference internal\" href=\"#module-django.db.transaction\" title=\"django.db.transaction\"><code class=\"xref py py-mod docutils literal notranslate\">django.db.transaction</code></a>.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.commit\">\n<span class=\"sig-name descname\">commit</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.commit\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.rollback\">\n<span class=\"sig-name descname\">rollback</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.rollback\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>These functions take a <code class=\"docutils literal notranslate\">using</code> argument which should be the name of a\ndatabase. If it isn't provided, Django uses the <code class=\"docutils literal notranslate\">&quot;default&quot;</code> database.</p>\n<p>Django will refuse to commit or to rollback when an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> block is\nactive, because that would break atomicity.</p>\n</section>\n<section id=\"topics-db-transactions-savepoints\">\n<span id=\"id3\"></span><h3>Savepoint<a class=\"heading-anchor\" href=\"#topics-db-transactions-savepoints\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A savepoint is a marker within a transaction that enables you to roll back\npart of a transaction, rather than the full transaction. Savepoints are\navailable with the SQLite (≥ 3.6.8), PostgreSQL, Oracle and MySQL (when using\nthe InnoDB storage engine) backends. Other backends provide the savepoint\nfunctions, but they're empty operations -- they don't actually do anything.</p>\n<p>Savepoints aren't especially useful if you are using autocommit, the default\nbehavior of Django. However, once you open a transaction with <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a>,\nyou build up a series of database operations awaiting a commit or rollback. If\nyou issue a rollback, the entire transaction is rolled back. Savepoints\nprovide the ability to perform a fine-grained rollback, rather than the full\nrollback that would be performed by <code class=\"docutils literal notranslate\">transaction.rollback()</code>.</p>\n<p>When the <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> decorator is nested, it creates a savepoint to allow\npartial commit or rollback. You're strongly encouraged to use <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a>\nrather than the functions described below, but they're still part of the\npublic API, and there's no plan to deprecate them.</p>\n<p>Each of these functions takes a <code class=\"docutils literal notranslate\">using</code> argument which should be the name of\na database for which the behavior applies.  If no <code class=\"docutils literal notranslate\">using</code> argument is\nprovided then the <code class=\"docutils literal notranslate\">&quot;default&quot;</code> database is used.</p>\n<p>Savepoints are controlled by three functions in <a class=\"reference internal\" href=\"#module-django.db.transaction\" title=\"django.db.transaction\"><code class=\"xref py py-mod docutils literal notranslate\">django.db.transaction</code></a>:</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.savepoint\">\n<span class=\"sig-name descname\">savepoint</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.savepoint\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Creates a new savepoint. This marks a point in the transaction that is\nknown to be in a &quot;good&quot; state. Returns the savepoint ID (<code class=\"docutils literal notranslate\">sid</code>).</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.savepoint_commit\">\n<span class=\"sig-name descname\">savepoint_commit</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sid</em>, <em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.savepoint_commit\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Releases savepoint <code class=\"docutils literal notranslate\">sid</code>. The changes performed since the savepoint was\ncreated become part of the transaction.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.savepoint_rollback\">\n<span class=\"sig-name descname\">savepoint_rollback</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sid</em>, <em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.savepoint_rollback\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Rolls back the transaction to savepoint <code class=\"docutils literal notranslate\">sid</code>.</p>\n</dd></dl>\n\n<p>These functions do nothing if savepoints aren't supported or if the database\nis in autocommit mode.</p>\n<p>In addition, there's a utility function:</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.clean_savepoints\">\n<span class=\"sig-name descname\">clean_savepoints</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.clean_savepoints\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Resets the counter used to generate unique savepoint IDs.</p>\n</dd></dl>\n\n<p>The following example demonstrates the use of savepoints:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"c1\"># open a transaction</span>\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span>atomic\n<span class=\"k\">def</span> <span class=\"nf\">viewfunc</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n\n    a<span class=\"o\">.</span>save<span class=\"p\">()</span>\n    <span class=\"c1\"># transaction now contains a.save()</span>\n\n    sid <span class=\"o\">=</span> transaction<span class=\"o\">.</span>savepoint<span class=\"p\">()</span>\n\n    b<span class=\"o\">.</span>save<span class=\"p\">()</span>\n    <span class=\"c1\"># transaction now contains a.save() and b.save()</span>\n\n    <span class=\"k\">if</span> want_to_keep_b<span class=\"p\">:</span>\n        transaction<span class=\"o\">.</span>savepoint_commit<span class=\"p\">(</span>sid<span class=\"p\">)</span>\n        <span class=\"c1\"># open transaction still contains a.save() and b.save()</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        transaction<span class=\"o\">.</span>savepoint_rollback<span class=\"p\">(</span>sid<span class=\"p\">)</span>\n        <span class=\"c1\"># open transaction now contains only a.save()</span>\n</code></pre></div>\n<p>Savepoints may be used to recover from a database error by performing a partial\nrollback. If you're doing this inside an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> block, the entire block\nwill still be rolled back, because it doesn't know you've handled the situation\nat a lower level! To prevent this, you can control the rollback behavior with\nthe following functions.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.get_rollback\">\n<span class=\"sig-name descname\">get_rollback</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.get_rollback\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.db.transaction.set_rollback\">\n<span class=\"sig-name descname\">set_rollback</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">rollback</em>, <em class=\"sig-param\">using<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.transaction.set_rollback\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Setting the rollback flag to <code class=\"docutils literal notranslate\">True</code> forces a rollback when exiting the\ninnermost atomic block. This may be useful to trigger a rollback without\nraising an exception.</p>\n<p>Setting it to <code class=\"docutils literal notranslate\">False</code> prevents such a rollback. Before doing that, make sure\nyou've rolled back the transaction to a known-good savepoint within the current\natomic block! Otherwise you're breaking atomicity and data corruption may\noccur.</p>\n</section>\n</section>\n<section id=\"database-specific-notes\">\n<h2>Database-specific notes<a class=\"heading-anchor\" href=\"#database-specific-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"savepoints-in-sqlite\">\n<span id=\"id4\"></span><h3>Savepoint di SQLite<a class=\"heading-anchor\" href=\"#savepoints-in-sqlite\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>While SQLite ≥ 3.6.8 supports savepoints, a flaw in the design of the\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/sqlite3.html#module-sqlite3\" title=\"(di Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">sqlite3</code></a> module makes them hardly usable.</p>\n<p>When autocommit is enabled, savepoints don't make sense. When it's disabled,\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/sqlite3.html#module-sqlite3\" title=\"(di Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">sqlite3</code></a> commits implicitly before savepoint statements. (In fact, it\ncommits before any statement other than <code class=\"docutils literal notranslate\">SELECT</code>, <code class=\"docutils literal notranslate\">INSERT</code>, <code class=\"docutils literal notranslate\">UPDATE</code>,\n<code class=\"docutils literal notranslate\">DELETE</code> and <code class=\"docutils literal notranslate\">REPLACE</code>.) This bug has two consequences:</p>\n<ul class=\"simple\">\n<li><p>The low level APIs for savepoints are only usable inside a transaction ie.\ninside an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> block.</p></li>\n<li><p>It's impossible to use <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> when autocommit is turned off.</p></li>\n</ul>\n</section>\n<section id=\"transactions-in-mysql\">\n<h3>Transaksi di MySQL<a class=\"heading-anchor\" href=\"#transactions-in-mysql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you're using MySQL, your tables may or may not support transactions; it\ndepends on your MySQL version and the table types you're using. (By\n&quot;table types,&quot; we mean something like &quot;InnoDB&quot; or &quot;MyISAM&quot;.) MySQL transaction\npeculiarities are outside the scope of this article, but the MySQL site has\n<a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-transactions.html\">information on MySQL transactions</a>.</p>\n<p>If your MySQL setup does <em>not</em> support transactions, then Django will always\nfunction in autocommit mode: statements will be executed and committed as soon\nas they're called. If your MySQL setup <em>does</em> support transactions, Django\nwill handle transactions as explained in this document.</p>\n</section>\n<section id=\"handling-exceptions-within-postgresql-transactions\">\n<h3>Penanganan pengecualian dalam transaksi PostgreSQL<a class=\"heading-anchor\" href=\"#handling-exceptions-within-postgresql-transactions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Catatan</p>\n<p>This section is relevant only if you're implementing your own transaction\nmanagement. This problem cannot occur in Django's default mode and\n<a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> handles it automatically.</p>\n</aside>\n<p>Inside a transaction, when a call to a PostgreSQL cursor raises an exception\n(typically <code class=\"docutils literal notranslate\">IntegrityError</code>), all subsequent SQL in the same transaction\nwill fail with the error &quot;current transaction is aborted, queries ignored\nuntil end of transaction block&quot;. While simple use of <code class=\"docutils literal notranslate\">save()</code> is unlikely\nto raise an exception in PostgreSQL, there are more advanced usage patterns\nwhich might, such as saving objects with unique fields, saving using the\nforce_insert/force_update flag, or invoking custom SQL.</p>\n<p>There are several ways to recover from this sort of error.</p>\n<section id=\"transaction-rollback\">\n<h4>Gulung kembali transaksi<a class=\"heading-anchor\" href=\"#transaction-rollback\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>The first option is to roll back the entire transaction. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>a<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Succeeds, but may be undone by transaction rollback</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    b<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Could throw exception</span>\n<span class=\"k\">except</span> IntegrityError<span class=\"p\">:</span>\n    transaction<span class=\"o\">.</span>rollback<span class=\"p\">()</span>\nc<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Succeeds, but a.save() may have been undone</span>\n</code></pre></div>\n<p>Calling <code class=\"docutils literal notranslate\">transaction.rollback()</code> rolls back the entire transaction. Any\nuncommitted database operations will be lost. In this example, the changes\nmade by <code class=\"docutils literal notranslate\">a.save()</code> would be lost, even though that operation raised no error\nitself.</p>\n</section>\n<section id=\"savepoint-rollback\">\n<h4>Savepoint rollback<a class=\"heading-anchor\" href=\"#savepoint-rollback\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>You can use <a class=\"reference internal\" href=\"#topics-db-transactions-savepoints\"><span class=\"std std-ref\">savepoints</span></a> to control\nthe extent of a rollback. Before performing a database operation that could\nfail, you can set or update the savepoint; that way, if the operation fails,\nyou can roll back the single offending operation, rather than the entire\ntransaction. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>a<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Succeeds, and never undone by savepoint rollback</span>\nsid <span class=\"o\">=</span> transaction<span class=\"o\">.</span>savepoint<span class=\"p\">()</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    b<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Could throw exception</span>\n    transaction<span class=\"o\">.</span>savepoint_commit<span class=\"p\">(</span>sid<span class=\"p\">)</span>\n<span class=\"k\">except</span> IntegrityError<span class=\"p\">:</span>\n    transaction<span class=\"o\">.</span>savepoint_rollback<span class=\"p\">(</span>sid<span class=\"p\">)</span>\nc<span class=\"o\">.</span>save<span class=\"p\">()</span> <span class=\"c1\"># Succeeds, and a.save() is never undone</span>\n</code></pre></div>\n<p>In this example, <code class=\"docutils literal notranslate\">a.save()</code> will not be undone in the case where\n<code class=\"docutils literal notranslate\">b.save()</code> raises an exception.</p>\n</section>\n</section>\n</section>","rootId":"module-django.db.transaction","toc":[{"title":"Mengelola transaksi basisdata","anchor":"managing-database-transactions","children":[{"title":"Kebiasaan transaksi awal Django","anchor":"django-s-default-transaction-behavior","children":[]},{"title":"Tying transactions to HTTP requests","anchor":"tying-transactions-to-http-requests","children":[]},{"title":"Mengendalikan transaksi secara eksplisit","anchor":"controlling-transactions-explicitly","children":[]}]},{"title":"Penyerahan otomatis","anchor":"autocommit","children":[{"title":"Kenapa Django menggunakan penyerahan otomatis","anchor":"why-django-uses-autocommit","children":[]},{"title":"Menonaktifkan pengelolaan transaksi","anchor":"deactivating-transaction-management","children":[]}]},{"title":"Melakukan tindakan setelah penyerahan","anchor":"performing-actions-after-commit","children":[{"title":"Savepoint","anchor":"savepoints","children":[]},{"title":"Urutan pelaksanaan","anchor":"order-of-execution","children":[]},{"title":"Penanganan pengecualian","anchor":"exception-handling","children":[]},{"title":"Waktu pelaksanaan","anchor":"timing-of-execution","children":[]},{"title":"Use in tests","anchor":"use-in-tests","children":[]},{"title":"Why no rollback hook?","anchor":"why-no-rollback-hook","children":[]}]},{"title":"Low-level APIs","anchor":"low-level-apis","children":[{"title":"Penyerahan otomatis","anchor":"managing-autocommit","children":[]},{"title":"Transaksi","anchor":"transactions","children":[]},{"title":"Savepoint","anchor":"topics-db-transactions-savepoints","children":[]}]},{"title":"Database-specific notes","anchor":"database-specific-notes","children":[{"title":"Savepoint di SQLite","anchor":"savepoints-in-sqlite","children":[]},{"title":"Transaksi di MySQL","anchor":"transactions-in-mysql","children":[]},{"title":"Penanganan pengecualian dalam transaksi PostgreSQL","anchor":"handling-exceptions-within-postgresql-transactions","children":[{"title":"Gulung kembali transaksi","anchor":"transaction-rollback","children":[]},{"title":"Savepoint rollback","anchor":"savepoint-rollback","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Menggunakan Django","url":"/id/1.9/topics/"},{"docname":"topics/db/index","title":"Model dan basisdata","url":"/id/1.9/topics/db/"}],"prev":{"docname":"topics/db/sql","title":"Performing raw SQL queries","url":"/id/1.9/topics/db/sql/"},"next":{"docname":"topics/db/multi-db","title":"Basisdata banyak","url":"/id/1.9/topics/db/multi-db/"},"formats":{"html":"/id/1.9/topics/db/transactions/","markdown":"/id/1.9/topics/db/transactions.md","json":"/id/1.9/topics/db/transactions.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/topics/db/transactions.txt","official":"https://docs.djangoproject.com/id/1.9/topics/db/transactions/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","es"]}