<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>database &amp;mdash; sandeepk</title>
    <link>https://blogs.dgplug.org/sandeepk/tag:database</link>
    <description></description>
    <pubDate>Sun, 19 Apr 2026 07:40:17 +0000</pubDate>
    <item>
      <title>Django: How to acquire a lock on the database rows? </title>
      <link>https://blogs.dgplug.org/sandeepk/django-how-to-acquire-a-lock-on-the-database-rows</link>
      <description>&lt;![CDATA[selectforupdate is the answer if you want to acquire a lock on the row. The lock is only released after the transaction is completed. This is similar to the Select for update statement in the SQL query.&#xA;&#xA;      Dealership.objects.selectforupdate().get(pk=&#39;iamid&#39;)&#xA;      # Here lock is only required on Dealership object&#xA;      Dealership.objects.selectrelated(&#39;oem&#39;).selectforupdate(of=(&#39;self&#39;,))&#xA;selectforupdate have these four arguments with these default value&#xA;nowait=False&#xA;skiplocked=False&#xA;of=()&#xA;nokey=False&#xA;&#xA;Let&#39;s see what these all arguments mean&#xA;&#xA;nowait&#xA;Think of the scenario where the lock is already acquired by another query, in this case, you want your query to wait or raise an error, This behavior can be controlled by nowait, If nowait=True we will raise the DatabaseError otherwise it will wait for the lock to be released.&#xA;skiplocked&#xA;As somewhat name implies, it helps to decide whether to consider a locked row in the evaluated query. If the skiplocked=true locked rows will not be considered.&#xA;&#xA;  nowait and skiplocked are mutually exclusive using both together will raise ValueError&#xA;&#xA;of&#xA;In selectforupdate when the query is evaluated, the lock is also acquired on the select related rows as in the query. If one doesn&#39;t wish the same, they can use of where they can specify fields to acquire a lock on&#xA;      Dealership.objects.selectrelated(&#39;oem&#39;).selectforupdate(of=(&#39;self&#39;,))&#xA;Just be sure we don&#39;t have any nullable relation with OEM&#xA;nokey&#xA;This helps you to create a weak lock. This means the other query can create new rows which refer to the locked rows (any reference relationship).&#xA;&#xA;Few more important points to keep in mind selectforupdate doesn&#39;t allow nullable relations, you have to explicitly exclude these nullable conditions. In auto-commit mode, selectforupdate fails with error TransactionManagementError you have to add code in a transaction explicitly. I have struggled around these points :).&#xA;&#xA;Here is all about selectforupdate which you require to know to use in your code and to do changes to your database.&#xA;&#xA;Cheers!&#xA;&#xA;Python&#xA;Django&#xA;ORM&#xA;Database&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><code>select_for_update</code> is the answer if you want to acquire a lock on the row. The lock is only released after the transaction is completed. This is similar to the <code>Select for update statement</code> in the SQL query.</p>

<pre><code class="language-python">&gt;&gt;&gt; Dealership.objects.select_for_update().get(pk=&#39;iamid&#39;)
&gt;&gt;&gt; # Here lock is only required on Dealership object
&gt;&gt;&gt; Dealership.objects.select_related(&#39;oem&#39;).select_for_update(of=(&#39;self&#39;,))
</code></pre>

<p><code>select_for_update</code> have these four arguments with these default value
– nowait=False
– skip<em>locked=False
– of=()
– no</em>key=False</p>

<p>Let&#39;s see what these all arguments mean</p>

<h2 id="nowait">nowait</h2>

<p>Think of the scenario where the lock is already acquired by another query, in this case, you want your query to wait or raise an error, This behavior can be controlled by <code>nowait</code>, If <code>nowait=True</code> we will raise the <code>DatabaseError</code> otherwise it will wait for the lock to be released.</p>

<h2 id="skip-locked">skip_locked</h2>

<p>As somewhat name implies, it helps to decide whether to consider a locked row in the evaluated query. If the <code>skip_locked=true</code> locked rows will not be considered.</p>

<blockquote><p>nowait and skip_locked are mutually exclusive using both together will raise ValueError</p></blockquote>

<h2 id="of">of</h2>

<p>In <code>select_for_update</code> when the query is evaluated, the lock is also acquired on the select related rows as in the query. If one doesn&#39;t wish the same, they can use <code>of</code> where they can specify fields to acquire a lock on</p>

<pre><code class="language-python">&gt;&gt;&gt; Dealership.objects.select_related(&#39;oem&#39;).select_for_update(of=(&#39;self&#39;,))
# Just be sure we don&#39;t have any nullable relation with OEM
</code></pre>

<h2 id="no-key">no_key</h2>

<p>This helps you to create a weak lock. This means the other query can create new rows which refer to the locked rows (any reference relationship).</p>

<p>Few more important points to keep in mind <code>select_for_update</code> doesn&#39;t allow nullable relations, you have to explicitly exclude these nullable conditions. In auto-commit mode, <code>select_for_update</code> fails with error <code>TransactionManagementError</code> you have to add code in a transaction explicitly. I have struggled around these points :).</p>

<p>Here is all about <code>select_for_update</code> which you require to know to use in your code and to do changes to your database.</p>

<p>Cheers!</p>

<p><a href="/sandeepk/tag:Python" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Python</span></a>
<a href="/sandeepk/tag:Django" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Django</span></a>
<a href="/sandeepk/tag:ORM" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ORM</span></a>
<a href="/sandeepk/tag:Database" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Database</span></a></p>
]]></content:encoded>
      <guid>https://blogs.dgplug.org/sandeepk/django-how-to-acquire-a-lock-on-the-database-rows</guid>
      <pubDate>Sat, 14 May 2022 14:06:03 +0000</pubDate>
    </item>
  </channel>
</rss>