{"title":"Database transactions","version":"2.2","locale":"es","docname":"topics/db/transactions","url":"/es/2.2/topics/db/transactions/","canonical":"https://djangodocs.dev/es/2.2/topics/db/transactions/","summary":"Django gives you a few ways to control how database transactions are managed. Managing database transactions Link to this heading # Django’s default transaction…","html":"<span id=\"database-transactions\"></span><h1>Database transactions<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 gives you a few ways to control how database transactions are managed.</p>\n<section id=\"managing-database-transactions\">\n<h2>Managing database transactions<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>Django’s default transaction behavior<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>Django’s default behavior is to run in autocommit mode. Each query is\nimmediately committed to the database, unless a transaction is active.\n<a class=\"reference internal\" href=\"#autocommit-details\"><span class=\"std std-ref\">See below for details</span></a>.</p>\n<p>Django uses transactions or savepoints automatically to guarantee the\nintegrity of ORM operations that require multiple queries, especially\n<a class=\"reference internal\" href=\"/es/2.2/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">delete()</span></a> and <a class=\"reference internal\" href=\"/es/2.2/topics/db/queries/#topics-db-queries-update\"><span class=\"std std-ref\">update()</span></a> queries.</p>\n<p>Django’s <a class=\"reference internal\" href=\"/es/2.2/topics/testing/tools/#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></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>A common way to handle transactions on the web is to wrap each request in a\ntransaction. Set <a class=\"reference internal\" href=\"/es/2.2/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ATOMIC_REQUESTS</span></code></a> to\n<code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> in the configuration of each database for which you want to enable\nthis behavior.</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\"><span class=\"pre\">atomic()</span></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\">Advertencia</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\">\n<p class=\"admonition-title\">Per-request transactions and streaming responses</p>\n<p>When a view returns a <a class=\"reference internal\" href=\"/es/2.2/ref/request-response/#django.http.StreamingHttpResponse\" title=\"django.http.StreamingHttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StreamingHttpResponse</span></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\"><span class=\"pre\">atomic()</span></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=\"/es/2.2/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ATOMIC_REQUESTS</span></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\"><span class=\"pre\">non_atomic_requests</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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=\"/es/2.2/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ATOMIC_REQUESTS</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">transaction</span>\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span><span class=\"n\">non_atomic_requests</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">do_stuff</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span><span class=\"n\">non_atomic_requests</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s1\">&#39;other&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_other_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">do_stuff_on_the_other_database</span><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>Controlling transactions explicitly<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\"><span class=\"pre\">atomic</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">savepoint</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></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\"><span class=\"pre\">atomic</span></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\"><span class=\"pre\">atomic</span></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\"><span class=\"pre\">atomic</span></code> is usable both as a <a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-decorator\" title=\"(en Python versión 3.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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">transaction</span>\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">viewfunc</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This code executes inside a transaction.</span>\n    <span class=\"n\">do_stuff</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>and as a <a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-context-manager\" title=\"(en Python versión 3.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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">transaction</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">viewfunc</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This code executes in autocommit mode (Django&#39;s default).</span>\n    <span class=\"n\">do_stuff</span><span class=\"p\">()</span>\n\n    <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>\n        <span class=\"c1\"># This code executes inside a transaction.</span>\n        <span class=\"n\">do_more_stuff</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Wrapping <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">IntegrityError</span><span class=\"p\">,</span> <span class=\"n\">transaction</span>\n\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">viewfunc</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">create_parent</span><span class=\"p\">()</span>\n\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>\n            <span class=\"n\">generate_relationships</span><span class=\"p\">()</span>\n    <span class=\"k\">except</span> <span class=\"n\">IntegrityError</span><span class=\"p\">:</span>\n        <span class=\"n\">handle_exception</span><span class=\"p\">()</span>\n\n    <span class=\"n\">add_children</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>In this example, even if <code class=\"docutils literal notranslate\"><span class=\"pre\">generate_relationships()</span></code> causes a database\nerror by breaking an integrity constraint, you can execute queries in\n<code class=\"docutils literal notranslate\"><span class=\"pre\">add_children()</span></code>, and the changes from <code class=\"docutils literal notranslate\"><span class=\"pre\">create_parent()</span></code> are still\nthere. Note that any operations attempted in <code class=\"docutils literal notranslate\"><span class=\"pre\">generate_relationships()</span></code>\nwill already have been rolled back safely when <code class=\"docutils literal notranslate\"><span class=\"pre\">handle_exception()</span></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\">\n<p class=\"admonition-title\">Avoid catching exceptions inside <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code>!</p>\n<p>When exiting an <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></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\"><span class=\"pre\">atomic</span></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=\"/es/2.2/ref/exceptions/#django.db.DatabaseError\" title=\"django.db.DatabaseError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">DatabaseError</span></code></a> and its\nsubclasses such as <a class=\"reference internal\" href=\"/es/2.2/ref/exceptions/#django.db.IntegrityError\" title=\"django.db.IntegrityError\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">IntegrityError</span></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\"><span class=\"pre\">atomic</span></code> block. If you attempt to run database\nqueries before the rollback happens, Django will raise a\n<a class=\"reference internal\" href=\"/es/2.2/ref/exceptions/#django.db.transaction.TransactionManagementError\" title=\"django.db.transaction.TransactionManagementError\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionManagementError</span></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\"><span class=\"pre\">atomic</span></code> block\nas shown above. If necessary, add an extra <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></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<aside class=\"admonition-you-may-need-to-manually-revert-model-state-when-rolling-back-a-transaction admonition\">\n<p class=\"admonition-title\">You may need to manually revert model state when rolling back a transaction.</p>\n<p>The values of a model’s fields won’t be reverted when a transaction\nrollback happens. This could lead to an inconsistent model state unless\nyou manually restore the original field values.</p>\n<p>For example, given <code class=\"docutils literal notranslate\"><span class=\"pre\">MyModel</span></code> with an <code class=\"docutils literal notranslate\"><span class=\"pre\">active</span></code> field, this snippet\nensures that the <code class=\"docutils literal notranslate\"><span class=\"pre\">if</span> <span class=\"pre\">obj.active</span></code> check at the end uses the correct\nvalue if updating <code class=\"docutils literal notranslate\"><span class=\"pre\">active</span></code> to <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> fails in the transaction:</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DatabaseError</span><span class=\"p\">,</span> <span class=\"n\">transaction</span>\n\n<span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"n\">MyModel</span><span class=\"p\">(</span><span class=\"n\">active</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">active</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n<span class=\"k\">except</span> <span class=\"n\">DatabaseError</span><span class=\"p\">:</span>\n    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">active</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n<span class=\"k\">if</span> <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">active</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</aside>\n<p>In order to guarantee atomicity, <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></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\"><span class=\"pre\">atomic</span></code> block will raise an exception.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> takes a <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> argument which should be the name of a\ndatabase. If this argument isn’t provided, Django uses the <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;default&quot;</span></code>\ndatabase.</p>\n<p>Under the hood, Django’s transaction management code:</p>\n<ul class=\"simple\">\n<li><p>opens a transaction when entering the outermost <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> block;</p></li>\n<li><p>creates a savepoint when entering an inner <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> block;</p></li>\n<li><p>releases or rolls back to the savepoint when exiting an inner block;</p></li>\n<li><p>commits or rolls back the transaction when exiting the outermost block.</p></li>\n</ul>\n<p>You can disable the creation of savepoints for inner blocks by setting the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">savepoint</span></code> argument to <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>. If an exception occurs, Django will\nperform the rollback when exiting the first parent block with a savepoint\nif there is one, and the outermost block otherwise. Atomicity is still\nguaranteed by the outer transaction. This option should only be used if\nthe overhead of savepoints is noticeable. It has the drawback of breaking\nthe error handling described above.</p>\n<p>You may use <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> when autocommit is turned off. It will only use\nsavepoints, even for the outermost block.</p>\n</dd></dl>\n\n<aside class=\"admonition-performance-considerations admonition\">\n<p class=\"admonition-title\">Performance considerations</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\"><span class=\"pre\">atomic()</span></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>Autocommit<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>Why Django uses autocommit<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>In the SQL standards, each SQL query starts a transaction, unless one is\nalready active. Such transactions must then be explicitly committed or rolled\nback.</p>\n<p>This isn’t always convenient for application developers. To alleviate this\nproblem, most databases provide an autocommit mode. When autocommit is turned\non and no transaction is active, each SQL query gets wrapped in its own\ntransaction. In other words, not only does each such query start a\ntransaction, but the transaction also gets automatically committed or rolled\nback, depending on whether the query succeeded.</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>To avoid this, you can <a class=\"reference internal\" href=\"#deactivate-transaction-management\"><span class=\"std std-ref\">deactivate the transaction management</span></a>, but it isn’t recommended.</p>\n</section>\n<section id=\"deactivating-transaction-management\">\n<span id=\"deactivate-transaction-management\"></span><h3>Deactivating transaction management<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=\"/es/2.2/ref/settings/#std-setting-DATABASE-AUTOCOMMIT\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTOCOMMIT</span></code></a> to <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></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>This requires you to commit explicitly every transaction, even those started\nby Django or by third-party libraries. Thus, this is best used in situations\nwhere you want to run your own transaction-controlling middleware or do\nsomething really strange.</p>\n</section>\n</section>\n<section id=\"performing-actions-after-commit\">\n<h2>Performing actions after commit<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<p>Sometimes you need to perform an action related to the current database\ntransaction, but only if the transaction successfully commits. Examples might\ninclude a <a class=\"reference external\" href=\"http://www.celeryproject.org/\">Celery</a> task, an email notification, or a cache invalidation.</p>\n<p>Django provides the <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\"><span class=\"pre\">on_commit()</span></code></a> function to register callback functions\nthat should be executed after a transaction is successfully committed:</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\"><span class=\"pre\">on_commit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">func</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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>Pass any function (that takes no arguments) to <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\"><span class=\"pre\">on_commit()</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">transaction</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </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\n<span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"n\">do_something</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>You can also wrap your function in a 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><span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"k\">lambda</span><span class=\"p\">:</span> <span class=\"n\">some_celery_task</span><span class=\"o\">.</span><span class=\"n\">delay</span><span class=\"p\">(</span><span class=\"s1\">&#39;arg1&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>The function you pass in will be called immediately after a hypothetical\ndatabase write made where <code class=\"docutils literal notranslate\"><span class=\"pre\">on_commit()</span></code> is called would be successfully\ncommitted.</p>\n<p>If you call <code class=\"docutils literal notranslate\"><span class=\"pre\">on_commit()</span></code> while there isn’t an active transaction, the\ncallback will be executed immediately.</p>\n<p>If that hypothetical database write is instead rolled back (typically when an\nunhandled exception is raised in an <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">atomic()</span></code></a> block), your function will\nbe discarded and never called.</p>\n<section id=\"savepoints\">\n<h3>Savepoints<a class=\"heading-anchor\" href=\"#savepoints\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Savepoints (i.e. nested <a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">atomic()</span></code></a> blocks) are handled correctly. That is,\nan <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\"><span class=\"pre\">on_commit()</span></code></a> callable registered after a savepoint (in a nested\n<a class=\"reference internal\" href=\"#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">atomic()</span></code></a> block) will be called after the outer transaction is committed,\nbut not if a rollback to that savepoint or any previous savepoint occurred\nduring the transaction:</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> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>  <span class=\"c1\"># Outer atomic, start a new transaction</span>\n    <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"n\">foo</span><span class=\"p\">)</span>\n\n    <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>  <span class=\"c1\"># Inner atomic block, create a savepoint</span>\n        <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"n\">bar</span><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>On the other hand, when a savepoint is rolled back (due to an exception being\nraised), the inner callable will not be called:</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> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>  <span class=\"c1\"># Outer atomic, start a new transaction</span>\n    <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"n\">foo</span><span class=\"p\">)</span>\n\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>  <span class=\"c1\"># Inner atomic block, create a savepoint</span>\n            <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">on_commit</span><span class=\"p\">(</span><span class=\"n\">bar</span><span class=\"p\">)</span>\n            <span class=\"k\">raise</span> <span class=\"n\">SomeError</span><span class=\"p\">()</span>  <span class=\"c1\"># Raising an exception - abort the savepoint</span>\n    <span class=\"k\">except</span> <span class=\"n\">SomeError</span><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>Order of execution<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>Exception handling<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\"><span class=\"pre\">on_commit()</span></code></a>.</p>\n</section>\n<section id=\"timing-of-execution\">\n<h3>Timing of execution<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>Your callbacks are executed <em>after</em> a successful commit, so a failure in a\ncallback will not cause the transaction to roll back. They are executed\nconditionally upon the success of the transaction, but they are not <em>part</em> of\nthe transaction. For the intended use cases (mail notifications, Celery tasks,\netc.), this should be fine. If it’s not (if your follow-up action is so\ncritical that its failure should mean the failure of the transaction itself),\nthen you don’t want to use the <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\"><span class=\"pre\">on_commit()</span></code></a> hook. Instead, you may want\n<a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Two-phase_commit_protocol\">two-phase commit</a> such as the <a class=\"reference external\" href=\"http://initd.org/psycopg/docs/usage.html#tpc\">psycopg Two-Phase Commit protocol support</a>\nand the <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\nspecification</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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">atomic()</span></code></a> (or <a class=\"reference internal\" href=\"/es/2.2/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ATOMIC_REQUESTS</span></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\"><span class=\"pre\">on_commit()</span></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=\"/es/2.2/topics/testing/tools/#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></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\"><span class=\"pre\">on_commit()</span></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\"><span class=\"pre\">on_commit()</span></code></a> callback, use a\n<a class=\"reference internal\" href=\"/es/2.2/topics/testing/tools/#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></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\"><span class=\"pre\">on_commit()</span></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\">Advertencia</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\"><span class=\"pre\">atomic()</span></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>Autocommit<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\"><span class=\"pre\">django.db.transaction</span></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\"><span class=\"pre\">get_autocommit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">set_autocommit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">autocommit</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">using</span></code> argument which should be the name of a\ndatabase. If it isn’t provided, Django uses the <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;default&quot;</span></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\"><span class=\"pre\">commit()</span></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\"><span class=\"pre\">rollback()</span></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\"><span class=\"pre\">atomic()</span></code></a> block is\nactive, because that would break atomicity.</p>\n</section>\n<section id=\"transactions\">\n<h3>Transactions<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\"><span class=\"pre\">set_autocommit()</span></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\"><span class=\"pre\">commit()</span></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\"><span class=\"pre\">rollback()</span></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\"><span class=\"pre\">django.db.transaction</span></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\"><span class=\"pre\">commit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">rollback</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">using</span></code> argument which should be the name of a\ndatabase. If it isn’t provided, Django uses the <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;default&quot;</span></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\"><span class=\"pre\">atomic()</span></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>Savepoints<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, PostgreSQL, Oracle, and MySQL (when using the InnoDB\nstorage engine) backends. Other backends provide the savepoint functions, but\nthey’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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">transaction.rollback()</span></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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">using</span></code> argument which should be the name of\na database for which the behavior applies.  If no <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> argument is\nprovided then the <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;default&quot;</span></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\"><span class=\"pre\">django.db.transaction</span></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\"><span class=\"pre\">savepoint</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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 «good» state. Returns the savepoint ID (<code class=\"docutils literal notranslate\"><span class=\"pre\">sid</span></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\"><span class=\"pre\">savepoint_commit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sid</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">sid</span></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\"><span class=\"pre\">savepoint_rollback</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sid</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">sid</span></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\"><span class=\"pre\">clean_savepoints</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">transaction</span>\n\n<span class=\"c1\"># open a transaction</span>\n<span class=\"nd\">@transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">viewfunc</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n\n    <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n    <span class=\"c1\"># transaction now contains a.save()</span>\n\n    <span class=\"n\">sid</span> <span class=\"o\">=</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint</span><span class=\"p\">()</span>\n\n    <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n    <span class=\"c1\"># transaction now contains a.save() and b.save()</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">want_to_keep_b</span><span class=\"p\">:</span>\n        <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint_commit</span><span class=\"p\">(</span><span class=\"n\">sid</span><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        <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint_rollback</span><span class=\"p\">(</span><span class=\"n\">sid</span><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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">get_rollback</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">set_rollback</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">rollback</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></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\"><span class=\"pre\">True</span></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\"><span class=\"pre\">False</span></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>Savepoints in 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 supports savepoints, a flaw in the design of the <a class=\"reference external\" href=\"https://docs.python.org/3/library/sqlite3.html#module-sqlite3\" title=\"(en Python versión 3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">sqlite3</span></code></a>\nmodule 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=\"(en Python versión 3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">sqlite3</span></code></a> commits implicitly before savepoint statements. (In fact, it\ncommits before any statement other than <code class=\"docutils literal notranslate\"><span class=\"pre\">SELECT</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">UPDATE</span></code>,\n<code class=\"docutils literal notranslate\"><span class=\"pre\">DELETE</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">REPLACE</span></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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">atomic()</span></code></a> when autocommit is turned off.</p></li>\n</ul>\n</section>\n<section id=\"transactions-in-mysql\">\n<h3>Transactions in 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«table types,» we mean something like «InnoDB» or «MyISAM».) 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/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>Handling exceptions within PostgreSQL transactions<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\">Nota</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\"><span class=\"pre\">atomic()</span></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\"><span class=\"pre\">IntegrityError</span></code>), all subsequent SQL in the same transaction\nwill fail with the error «current transaction is aborted, queries ignored\nuntil end of transaction block». While simple use of <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></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>Transaction rollback<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><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">save</span><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    <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span> <span class=\"c1\"># Could throw exception</span>\n<span class=\"k\">except</span> <span class=\"n\">IntegrityError</span><span class=\"p\">:</span>\n    <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">rollback</span><span class=\"p\">()</span>\n<span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">save</span><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\"><span class=\"pre\">transaction.rollback()</span></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\"><span class=\"pre\">a.save()</span></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><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span> <span class=\"c1\"># Succeeds, and never undone by savepoint rollback</span>\n<span class=\"n\">sid</span> <span class=\"o\">=</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint</span><span class=\"p\">()</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span> <span class=\"c1\"># Could throw exception</span>\n    <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint_commit</span><span class=\"p\">(</span><span class=\"n\">sid</span><span class=\"p\">)</span>\n<span class=\"k\">except</span> <span class=\"n\">IntegrityError</span><span class=\"p\">:</span>\n    <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">savepoint_rollback</span><span class=\"p\">(</span><span class=\"n\">sid</span><span class=\"p\">)</span>\n<span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">save</span><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\"><span class=\"pre\">a.save()</span></code> will not be undone in the case where\n<code class=\"docutils literal notranslate\"><span class=\"pre\">b.save()</span></code> raises an exception.</p>\n</section>\n</section>\n</section>","rootId":"module-django.db.transaction","toc":[{"title":"Managing database transactions","anchor":"managing-database-transactions","children":[{"title":"Django’s default transaction behavior","anchor":"django-s-default-transaction-behavior","children":[]},{"title":"Tying transactions to HTTP requests","anchor":"tying-transactions-to-http-requests","children":[]},{"title":"Controlling transactions explicitly","anchor":"controlling-transactions-explicitly","children":[]}]},{"title":"Autocommit","anchor":"autocommit","children":[{"title":"Why Django uses autocommit","anchor":"why-django-uses-autocommit","children":[]},{"title":"Deactivating transaction management","anchor":"deactivating-transaction-management","children":[]}]},{"title":"Performing actions after commit","anchor":"performing-actions-after-commit","children":[{"title":"Savepoints","anchor":"savepoints","children":[]},{"title":"Order of execution","anchor":"order-of-execution","children":[]},{"title":"Exception handling","anchor":"exception-handling","children":[]},{"title":"Timing of execution","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":"Autocommit","anchor":"managing-autocommit","children":[]},{"title":"Transactions","anchor":"transactions","children":[]},{"title":"Savepoints","anchor":"topics-db-transactions-savepoints","children":[]}]},{"title":"Database-specific notes","anchor":"database-specific-notes","children":[{"title":"Savepoints in SQLite","anchor":"savepoints-in-sqlite","children":[]},{"title":"Transactions in MySQL","anchor":"transactions-in-mysql","children":[]},{"title":"Handling exceptions within PostgreSQL transactions","anchor":"handling-exceptions-within-postgresql-transactions","children":[{"title":"Transaction rollback","anchor":"transaction-rollback","children":[]},{"title":"Savepoint rollback","anchor":"savepoint-rollback","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Using Django","url":"/es/2.2/topics/"},{"docname":"topics/db/index","title":"Models and databases","url":"/es/2.2/topics/db/"}],"prev":{"docname":"topics/db/sql","title":"Performing raw SQL queries","url":"/es/2.2/topics/db/sql/"},"next":{"docname":"topics/db/multi-db","title":"Multiple databases","url":"/es/2.2/topics/db/multi-db/"},"formats":{"html":"/es/2.2/topics/db/transactions/","markdown":"/es/2.2/topics/db/transactions.md","json":"/es/2.2/topics/db/transactions.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/topics/db/transactions.txt","official":"https://docs.djangoproject.com/es/2.2/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","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}