title: Django & MariaDB/MySQL: Does select_for_update lock rows from subqueries? Causing deadlocks?
body: <p>Software: Django 2.1.0, Python 3.7.1, MariaDB 10.3.8, Linux Ubuntu 18LTS</p>
  
  <p>We recently added some load to a new application, and starting observing lots of deadlocks.  After a lot digging, I found out that the Django select_for_update query resulted in an SQL with several subqueries (3 or 4).   In all deadlocks I've seeen so far, at least one of the transactions involves this SQL with multiple subqueries.</p>
  
  <p><strong>my question is... Does the select_for_udpate lock records from every table involved?</strong> In my case, would record from the main SELECT, and from other tables used by subqueries get locked? Or only records from the main SELECT?</p>
  
  <p>From Django docs:</p>
  
  <blockquote>
    <p>By default, select_for_update() locks all rows that are selected by the query. For example, rows of related objects specified in select_related() are locked in addition to rows of the queryset’s model. </p>
  </blockquote>
  
  <p>However, I'm not using select_related() , at least I don't put it explicitly.</p>
  
  <p>Summary of my app: </p>
  
  <pre><code>with transaction.atomic():
     ModelName.objects.select_for_update().filter(...)
     ...
     update record that is locked
     ...
  </code></pre>
  
  <ul>
  <li>50+ clients sending queries to the database concurrently</li>
  <li>Some of those queries ask for the same record. Meaning different transactions will run the same SQL at the same time.</li>
  </ul>
  
  <p>After a lot of reading, I did the following to try to get the deadlock under control:</p>
  
  <p>1- Try/Catch exception error '1213' (deadlock). When this happens, wait 30 seconds and retry the query.  Here, I rely on the ROLLBACK function from the database engine.
  Also, print output of SHOW ENGINE INNODB STATUS and SHOW PROCESSLIST. But SHOW PROCESSLIST doesn't give useful information.</p>
  
  <p>2- Modify the Django select_on_update so that it doesn't build an SQL with subqueries. Now, the SQL generated contains a single WHERE with values and no subqueries. </p>
  
  <p>Anything else that could be done to reduce the deadlocks?</p>