Merge pull request #836 from taigaio/Fixing-deadlocks-on-update_attr_in_bulk_for_ids
Fixing deadlocks on update_attr_in_bulk_for_idsremotes/origin/issue/4795/notification_even_they_are_disabled
commit
7488878550
|
@ -18,11 +18,10 @@
|
||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
from django.db import DatabaseError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.shortcuts import _get_queryset
|
from django.shortcuts import _get_queryset
|
||||||
|
|
||||||
from django_pglocks import advisory_lock
|
|
||||||
|
|
||||||
from . import functions
|
from . import functions
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
@ -45,7 +44,7 @@ def get_object_or_none(klass, *args, **kwargs):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_typename_for_model_class(model:object, for_concrete_model=True) -> str:
|
def get_typename_for_model_class(model: object, for_concrete_model=True) -> str:
|
||||||
"""
|
"""
|
||||||
Get typename for model instance.
|
Get typename for model instance.
|
||||||
"""
|
"""
|
||||||
|
@ -101,6 +100,7 @@ def save_in_bulk(instances, callback=None, precall=None, **save_options):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def update_in_bulk(instances, list_of_new_values, callback=None, precall=None):
|
def update_in_bulk(instances, list_of_new_values, callback=None, precall=None):
|
||||||
"""Update a list of model instances.
|
"""Update a list of model instances.
|
||||||
|
@ -123,6 +123,7 @@ def update_in_bulk(instances, list_of_new_values, callback=None, precall=None):
|
||||||
callback(instance)
|
callback(instance)
|
||||||
|
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
def update_attr_in_bulk_for_ids(values, attr, model):
|
def update_attr_in_bulk_for_ids(values, attr, model):
|
||||||
"""Update a table using a list of ids.
|
"""Update a table using a list of ids.
|
||||||
|
|
||||||
|
@ -147,7 +148,18 @@ def update_attr_in_bulk_for_ids(values, attr, model):
|
||||||
attr=attr)
|
attr=attr)
|
||||||
|
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
cursor.execute(sql)
|
|
||||||
|
# We can have deadlocks with multiple updates over the same object
|
||||||
|
# In that situation we just retry
|
||||||
|
def _run_sql(retries=0, max_retries=3):
|
||||||
|
try:
|
||||||
|
cursor.execute(sql)
|
||||||
|
except DatabaseError:
|
||||||
|
print("retries", 0)
|
||||||
|
if retries < max_retries:
|
||||||
|
_run_sql(retries + 1)
|
||||||
|
|
||||||
|
transaction.on_commit(_run_sql)
|
||||||
|
|
||||||
|
|
||||||
def to_tsquery(term):
|
def to_tsquery(term):
|
||||||
|
@ -230,10 +242,10 @@ def to_tsquery(term):
|
||||||
if not bit:
|
if not bit:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if bit.startswith('"') and bit.endswith('"') and len(bit)>2:
|
if bit.startswith('"') and bit.endswith('"') and len(bit) > 2:
|
||||||
res.append(bit.replace('"', "'"))
|
res.append(bit.replace('"', "'"))
|
||||||
else:
|
else:
|
||||||
res.append("'%s':*" %(bit.replace("'", ""), ))
|
res.append("'%s':*" % (bit.replace("'", ""), ))
|
||||||
|
|
||||||
res.append("&")
|
res.append("&")
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ import pytest
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db(transaction=True)
|
||||||
|
|
||||||
class ExpiredSigner(signing.TimestampSigner):
|
class ExpiredSigner(signing.TimestampSigner):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -33,7 +33,7 @@ from taiga.projects.userstories import services, models
|
||||||
from .. import factories as f
|
from .. import factories as f
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db(transaction=True)
|
||||||
|
|
||||||
|
|
||||||
def test_get_userstories_from_bulk():
|
def test_get_userstories_from_bulk():
|
||||||
|
|
Loading…
Reference in New Issue