Changes between Initial Version and Version 11 of Ticket #34523


Ignore:
Timestamp:
Apr 28, 2023, 8:10:56 AM (17 months ago)
Author:
Anton Plotkin
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #34523

    • Property Cc Anton Plotkin added
    • Property Summary update_or_create not work in parallel insertionModel.objects.update_or_create method sometimes raises TransactionManagementError
  • Ticket #34523 – Description

    initial v11  
    1 I am tests on mariadb 10.5.19 (myisam).
    2 This test work fine on django-3.2.16
     1When using with **myisam**-only database the method **update_or_create** can occur a TransactionManagementError exception if creating a record was unsuccessful (because of IntegrityError, for example the record with a same primary key was already created by another process). 
    32
     3The problem has started after the upgrading from Django 3.2.16 to 4.1.7
     4
     5The test below just simulates a parallel insertion of the record with the same PK^
     6
     7Database backend: mariadb server (10.5.19) (default-storage-engine is **myisam**).
     8
     9This test works fine with Django 3.2.16 and fails on Django 4.1.7+:
    410{{{
    511class TransactionManagementErrorTest(TestCase):
    612
    713    class TestModel(models.Model):
     14        managed = False
    815        field = models.IntegerField(null=True)
    916
     
    4249        self.TestModel.objects.update_or_create(id=1, defaults={'field': 2})
    4350}}}
     51
     52**Exception**: django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
     53
     54**Failure stack:**
     55{{{
     56Traceback (most recent call last):
     57  File "/home/alex/workspace/test_TransactionManagementError/mysite/polls/tests.py", line 47, in test_update_or_create
     58    self.TestModel.objects.update_or_create(id=1, defaults={'field': 2})
     59  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/manager.py", line 87, in manager_method
     60    return getattr(self.get_queryset(), name)(*args, **kwargs)
     61  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 949, in update_or_create
     62    obj, created = self.select_for_update().get_or_create(defaults, **kwargs)
     63  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 926, in get_or_create
     64    return self.get(**kwargs), False
     65  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 633, in get
     66    num = len(clone)
     67  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 380, in __len__
     68    self._fetch_all()
     69  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 1881, in _fetch_all
     70    self._result_cache = list(self._iterable_class(self))
     71  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 91, in __iter__
     72    results = compiler.execute_sql(
     73  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1560, in execute_sql
     74    cursor.execute(sql, params)
     75  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 67, in execute
     76    return self._execute_with_wrappers(
     77  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
     78    return executor(sql, params, many, context)
     79  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 83, in _execute
     80    self.db.validate_no_broken_transaction()
     81  File "/home/alex/workspace/test_TransactionManagementError/.venv/lib/python3.9/site-packages/django/db/backends/base/base.py", line 531, in validate_no_broken_transaction
     82    raise TransactionManagementError(
     83django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
     84}}}
Back to Top