mirror of
https://github.com/evennia/evennia.git
synced 2026-03-22 15:56:30 +01:00
443 lines
No EOL
39 KiB
HTML
443 lines
No EOL
39 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>django.db.transaction — Evennia latest documentation</title>
|
|
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
|
|
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d75fae25" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/nature.css?v=245aff17" />
|
|
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
|
<script src="../../../_static/documentation_options.js?v=c6e86fd7"></script>
|
|
<script src="../../../_static/doctools.js?v=9bcbadda"></script>
|
|
<script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<link rel="index" title="Index" href="../../../genindex.html" />
|
|
<link rel="search" title="Search" href="../../../search.html" />
|
|
</head><body>
|
|
|
|
|
|
|
|
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../../../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="../../../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" accesskey="U">Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">django.db.transaction</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
|
|
<div class="documentwrapper">
|
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
<div class="sphinxsidebarwrapper">
|
|
<search id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../../../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</search>
|
|
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
|
|
<ul>
|
|
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
|
|
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
|
|
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
|
|
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
|
<li>
|
|
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
|
|
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
|
|
<a href="https://evennia.blogspot.com/">Blog</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for django.db.transaction</h1><div class="highlight"><pre>
|
|
<span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContextDecorator</span><span class="p">,</span> <span class="n">contextmanager</span>
|
|
|
|
<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="p">(</span>
|
|
<span class="n">DEFAULT_DB_ALIAS</span><span class="p">,</span>
|
|
<span class="n">DatabaseError</span><span class="p">,</span>
|
|
<span class="n">Error</span><span class="p">,</span>
|
|
<span class="n">ProgrammingError</span><span class="p">,</span>
|
|
<span class="n">connections</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">TransactionManagementError</span><span class="p">(</span><span class="n">ProgrammingError</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Transaction management is used improperly."""</span>
|
|
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_connection</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Get a database connection by name, or the default database connection</span>
|
|
<span class="sd"> if no name is provided. This is a private API.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">using</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">using</span> <span class="o">=</span> <span class="n">DEFAULT_DB_ALIAS</span>
|
|
<span class="k">return</span> <span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_autocommit</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the autocommit status of the connection."""</span>
|
|
<span class="k">return</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">get_autocommit</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">set_autocommit</span><span class="p">(</span><span class="n">autocommit</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Set the autocommit status of the connection."""</span>
|
|
<span class="k">return</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">set_autocommit</span><span class="p">(</span><span class="n">autocommit</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">commit</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Commit a transaction."""</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">rollback</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Roll back a transaction."""</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">savepoint</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Create a savepoint (if supported and required by the backend) inside the</span>
|
|
<span class="sd"> current transaction. Return an identifier for the savepoint that will be</span>
|
|
<span class="sd"> used for the subsequent rollback or commit.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">savepoint</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">savepoint_rollback</span><span class="p">(</span><span class="n">sid</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Roll back the most recent savepoint (if one exists). Do nothing if</span>
|
|
<span class="sd"> savepoints are not supported.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">savepoint_rollback</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">savepoint_commit</span><span class="p">(</span><span class="n">sid</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Commit the most recent savepoint (if one exists). Do nothing if</span>
|
|
<span class="sd"> savepoints are not supported.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">savepoint_commit</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">clean_savepoints</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Reset the counter used to generate unique savepoint ids in this thread.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">clean_savepoints</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_rollback</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the "needs rollback" flag -- for *advanced use* only."""</span>
|
|
<span class="k">return</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">get_rollback</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">set_rollback</span><span class="p">(</span><span class="n">rollback</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Set or unset the "needs rollback" flag -- for *advanced use* only.</span>
|
|
|
|
<span class="sd"> When `rollback` is `True`, trigger a rollback when exiting the innermost</span>
|
|
<span class="sd"> enclosing atomic block that has `savepoint=True` (that's the default). Use</span>
|
|
<span class="sd"> this to force a rollback without raising an exception.</span>
|
|
|
|
<span class="sd"> When `rollback` is `False`, prevent such a rollback. Use this only after</span>
|
|
<span class="sd"> rolling back to a known-good state! Otherwise, you break the atomic block</span>
|
|
<span class="sd"> and data corruption may occur.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">set_rollback</span><span class="p">(</span><span class="n">rollback</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@contextmanager</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">mark_for_rollback_on_error</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Internal low-level utility to mark a transaction as "needs rollback" when</span>
|
|
<span class="sd"> an exception is raised while not enforcing the enclosed block to be in a</span>
|
|
<span class="sd"> transaction. This is needed by Model.save() and friends to avoid starting a</span>
|
|
<span class="sd"> transaction when in autocommit mode and a single query is executed.</span>
|
|
|
|
<span class="sd"> It's equivalent to:</span>
|
|
|
|
<span class="sd"> connection = get_connection(using)</span>
|
|
<span class="sd"> if connection.get_autocommit():</span>
|
|
<span class="sd"> yield</span>
|
|
<span class="sd"> else:</span>
|
|
<span class="sd"> with transaction.atomic(using=using, savepoint=False):</span>
|
|
<span class="sd"> yield</span>
|
|
|
|
<span class="sd"> but it uses low-level utilities to avoid performance overhead.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">yield</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
|
|
<span class="n">connection</span> <span class="o">=</span> <span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">rollback_exc</span> <span class="o">=</span> <span class="n">exc</span>
|
|
<span class="k">raise</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">on_commit</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">robust</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Register `func` to be called when the current transaction is committed.</span>
|
|
<span class="sd"> If the current transaction is rolled back, `func` will not be called.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">get_connection</span><span class="p">(</span><span class="n">using</span><span class="p">)</span><span class="o">.</span><span class="n">on_commit</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">robust</span><span class="p">)</span>
|
|
|
|
|
|
<span class="c1">#################################</span>
|
|
<span class="c1"># Decorators / context managers #</span>
|
|
<span class="c1">#################################</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Atomic</span><span class="p">(</span><span class="n">ContextDecorator</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Guarantee the atomic execution of a given block.</span>
|
|
|
|
<span class="sd"> An instance can be used either as a decorator or as a context manager.</span>
|
|
|
|
<span class="sd"> When it's used as a decorator, __call__ wraps the execution of the</span>
|
|
<span class="sd"> decorated function in the instance itself, used as a context manager.</span>
|
|
|
|
<span class="sd"> When it's used as a context manager, __enter__ creates a transaction or a</span>
|
|
<span class="sd"> savepoint, depending on whether a transaction is already in progress, and</span>
|
|
<span class="sd"> __exit__ commits the transaction or releases the savepoint on normal exit,</span>
|
|
<span class="sd"> and rolls back the transaction or to the savepoint on exceptions.</span>
|
|
|
|
<span class="sd"> It's possible to disable the creation of savepoints if the goal is to</span>
|
|
<span class="sd"> ensure that some code runs within a transaction without creating overhead.</span>
|
|
|
|
<span class="sd"> A stack of savepoints identifiers is maintained as an attribute of the</span>
|
|
<span class="sd"> connection. None denotes the absence of a savepoint.</span>
|
|
|
|
<span class="sd"> This allows reentrancy even if the same AtomicWrapper is reused. For</span>
|
|
<span class="sd"> example, it's possible to define `oa = atomic('other')` and use `@oa` or</span>
|
|
<span class="sd"> `with oa:` multiple times.</span>
|
|
|
|
<span class="sd"> Since database connections are thread-local, this is thread-safe.</span>
|
|
|
|
<span class="sd"> An atomic block can be tagged as durable. In this case, raise a</span>
|
|
<span class="sd"> RuntimeError if it's nested within another atomic block. This guarantees</span>
|
|
<span class="sd"> that database changes in a durable block are committed to the database when</span>
|
|
<span class="sd"> the block exists without error.</span>
|
|
|
|
<span class="sd"> This is a private API.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">using</span><span class="p">,</span> <span class="n">savepoint</span><span class="p">,</span> <span class="n">durable</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">using</span> <span class="o">=</span> <span class="n">using</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">savepoint</span> <span class="o">=</span> <span class="n">savepoint</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">durable</span> <span class="o">=</span> <span class="n">durable</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_from_testcase</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">connection</span> <span class="o">=</span> <span class="n">get_connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">using</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">durable</span>
|
|
<span class="ow">and</span> <span class="n">connection</span><span class="o">.</span><span class="n">atomic_blocks</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">atomic_blocks</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">_from_testcase</span>
|
|
<span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span>
|
|
<span class="s2">"A durable atomic block cannot be nested within another "</span>
|
|
<span class="s2">"atomic block."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="c1"># Reset state when entering an outermost atomic block.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">commit_on_exit</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">get_autocommit</span><span class="p">():</span>
|
|
<span class="c1"># Pretend we're already in an atomic block to bypass the code</span>
|
|
<span class="c1"># that disables autocommit to enter a transaction, and make a</span>
|
|
<span class="c1"># note to deal with this case in __exit__.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">commit_on_exit</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="c1"># We're already in a transaction; create a savepoint, unless we</span>
|
|
<span class="c1"># were told not to or we're already waiting for a rollback. The</span>
|
|
<span class="c1"># second condition avoids creating useless savepoints and prevents</span>
|
|
<span class="c1"># overwriting needs_rollback until the rollback is performed.</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">savepoint</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span><span class="p">:</span>
|
|
<span class="n">sid</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">savepoint</span><span class="p">()</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">set_autocommit</span><span class="p">(</span>
|
|
<span class="kc">False</span><span class="p">,</span> <span class="n">force_begin_transaction_with_broken_autocommit</span><span class="o">=</span><span class="kc">True</span>
|
|
<span class="p">)</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span> <span class="o">=</span> <span class="kc">True</span>
|
|
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">atomic_blocks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
|
|
<span class="n">connection</span> <span class="o">=</span> <span class="n">get_connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">using</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">atomic_blocks</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">savepoint_ids</span><span class="p">:</span>
|
|
<span class="n">sid</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">savepoint_ids</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Prematurely unset this flag to allow using commit or rollback.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">closed_in_transaction</span><span class="p">:</span>
|
|
<span class="c1"># The database will perform a rollback by itself.</span>
|
|
<span class="c1"># Wait until we exit the outermost block.</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="k">elif</span> <span class="n">exc_type</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="c1"># Release savepoint if there is one</span>
|
|
<span class="k">if</span> <span class="n">sid</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_commit</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">DatabaseError</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_rollback</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="c1"># The savepoint won't be reused. Release it to</span>
|
|
<span class="c1"># minimize overhead for the database server.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_commit</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">Error</span><span class="p">:</span>
|
|
<span class="c1"># If rolling back to a savepoint fails, mark for</span>
|
|
<span class="c1"># rollback at a higher level and avoid shadowing</span>
|
|
<span class="c1"># the original exception.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">raise</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Commit transaction</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="n">DatabaseError</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="n">Error</span><span class="p">:</span>
|
|
<span class="c1"># An error during rollback means that something</span>
|
|
<span class="c1"># went wrong with the connection. Drop it.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
<span class="k">raise</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># This flag will be set to True again if there isn't a savepoint</span>
|
|
<span class="c1"># allowing to perform the rollback at this level.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="c1"># Roll back to savepoint if there is one, mark for rollback</span>
|
|
<span class="c1"># otherwise.</span>
|
|
<span class="k">if</span> <span class="n">sid</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_rollback</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="c1"># The savepoint won't be reused. Release it to</span>
|
|
<span class="c1"># minimize overhead for the database server.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">savepoint_commit</span><span class="p">(</span><span class="n">sid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">Error</span><span class="p">:</span>
|
|
<span class="c1"># If rolling back to a savepoint fails, mark for</span>
|
|
<span class="c1"># rollback at a higher level and avoid shadowing</span>
|
|
<span class="c1"># the original exception.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Roll back transaction</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="n">Error</span><span class="p">:</span>
|
|
<span class="c1"># An error during rollback means that something</span>
|
|
<span class="c1"># went wrong with the connection. Drop it.</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="c1"># Outermost block exit when autocommit was enabled.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">closed_in_transaction</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">set_autocommit</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="c1"># Outermost block exit when autocommit was disabled.</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">savepoint_ids</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">commit_on_exit</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">connection</span><span class="o">.</span><span class="n">closed_in_transaction</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">in_atomic_block</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
|
|
<div class="viewcode-block" id="atomic">
|
|
<a class="viewcode-back" href="../../../api/evennia.utils.idmapper.models.html#evennia.utils.idmapper.models.atomic">[docs]</a>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">atomic</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">savepoint</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">durable</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="c1"># Bare decorator: @atomic -- although the first argument is called</span>
|
|
<span class="c1"># `using`, it's actually the function being decorated.</span>
|
|
<span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">using</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Atomic</span><span class="p">(</span><span class="n">DEFAULT_DB_ALIAS</span><span class="p">,</span> <span class="n">savepoint</span><span class="p">,</span> <span class="n">durable</span><span class="p">)(</span><span class="n">using</span><span class="p">)</span>
|
|
<span class="c1"># Decorator: @atomic(...) or context manager: with atomic(...): ...</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">Atomic</span><span class="p">(</span><span class="n">using</span><span class="p">,</span> <span class="n">savepoint</span><span class="p">,</span> <span class="n">durable</span><span class="p">)</span></div>
|
|
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_non_atomic_requests</span><span class="p">(</span><span class="n">view</span><span class="p">,</span> <span class="n">using</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">view</span><span class="o">.</span><span class="n">_non_atomic_requests</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">using</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="n">view</span><span class="o">.</span><span class="n">_non_atomic_requests</span> <span class="o">=</span> <span class="p">{</span><span class="n">using</span><span class="p">}</span>
|
|
<span class="k">return</span> <span class="n">view</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">non_atomic_requests</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">using</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_non_atomic_requests</span><span class="p">(</span><span class="n">using</span><span class="p">,</span> <span class="n">DEFAULT_DB_ALIAS</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">using</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">using</span> <span class="o">=</span> <span class="n">DEFAULT_DB_ALIAS</span>
|
|
<span class="k">return</span> <span class="k">lambda</span> <span class="n">view</span><span class="p">:</span> <span class="n">_non_atomic_requests</span><span class="p">(</span><span class="n">view</span><span class="p">,</span> <span class="n">using</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../../../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="../../../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">django.db.transaction</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2024, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
|
</div>
|
|
</body>
|
|
</html> |