Commit 477d6dd2 by John Eskew Committed by GitHub

Merge pull request #13309 from edx/release

Hotfix for TNL-5365
parents 2e8e51c3 9af50a75
......@@ -139,7 +139,7 @@ class TestStudentModuleStorage(OtherUserFailureTestMixin, TestCase):
# to discover if something other than the DjangoXBlockUserStateClient
# has written to the StudentModule (such as UserStateCache setting the score
# on the StudentModule).
with self.assertNumQueries(2, using='default'):
with self.assertNumQueries(4, using='default'):
with self.assertNumQueries(1, using='student_module_history'):
self.kvs.set(user_state_key('a_field'), 'new_value')
self.assertEquals(1, StudentModule.objects.all().count())
......@@ -152,7 +152,7 @@ class TestStudentModuleStorage(OtherUserFailureTestMixin, TestCase):
# to discover if something other than the DjangoXBlockUserStateClient
# has written to the StudentModule (such as UserStateCache setting the score
# on the StudentModule).
with self.assertNumQueries(2, using='default'):
with self.assertNumQueries(4, using='default'):
with self.assertNumQueries(1, using='student_module_history'):
self.kvs.set(user_state_key('not_a_field'), 'new_value')
self.assertEquals(1, StudentModule.objects.all().count())
......@@ -206,7 +206,7 @@ class TestStudentModuleStorage(OtherUserFailureTestMixin, TestCase):
# We also need to read the database to discover if something other than the
# DjangoXBlockUserStateClient has written to the StudentModule (such as
# UserStateCache setting the score on the StudentModule).
with self.assertNumQueries(2, using="default"):
with self.assertNumQueries(4, using="default"):
with self.assertNumQueries(1, using="student_module_history"):
self.kvs.set_many(kv_dict)
......
......@@ -6,7 +6,7 @@ data in a Django ORM model.
import itertools
from operator import attrgetter
from time import time
import logging
try:
import simplejson as json
except ImportError:
......@@ -14,10 +14,14 @@ except ImportError:
import dogstats_wrapper as dog_stats_api
from django.contrib.auth.models import User
from django.db import transaction
from django.db.utils import IntegrityError
from xblock.fields import Scope
from courseware.models import StudentModule, BaseStudentModuleHistory
from edx_user_state_client.interface import XBlockUserStateClient, XBlockUserState
log = logging.getLogger(__name__)
class DjangoXBlockUserStateClient(XBlockUserStateClient):
"""
......@@ -222,8 +226,19 @@ class DjangoXBlockUserStateClient(XBlockUserStateClient):
current_state.update(state)
num_fields_after = len(current_state)
student_module.state = json.dumps(current_state)
# We just read this object, so we know that we can do an update
student_module.save(force_update=True)
try:
with transaction.atomic():
# Updating the object - force_update guarantees no INSERT will occur.
student_module.save(force_update=True)
except IntegrityError:
# The UPDATE above failed. Log information - but ignore the error.
# See https://openedx.atlassian.net/browse/TNL-5365
log.warning("set_many: IntegrityError for student {} - course_id {} - usage key {}".format(
user, repr(unicode(usage_key.course_key)), usage_key
))
log.warning("set_many: All {} block keys: {}".format(
len(block_keys_to_state), block_keys_to_state.keys()
))
# The rest of this method exists only to submit DataDog events.
# Remove it once we're no longer interested in the data.
......
......@@ -44,7 +44,7 @@ edx-lint==0.4.3
edx-django-oauth2-provider==1.1.1
edx-django-sites-extensions==2.0.1
edx-oauth2-provider==1.1.3
edx-opaque-keys==0.3.2
edx-opaque-keys==0.2.1
edx-organizations==0.4.1
edx-rest-api-client==1.2.1
edx-search==0.1.2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment