parent
4178488881
commit
83be40760a
|
@ -5,7 +5,7 @@ import traceback
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from django.db import DatabaseError, IntegrityError
|
from django.db import DatabaseError, IntegrityError, connection
|
||||||
from django.test import (
|
from django.test import (
|
||||||
TestCase, TransactionTestCase, ignore_warnings, skipUnlessDBFeature,
|
TestCase, TransactionTestCase, ignore_warnings, skipUnlessDBFeature,
|
||||||
)
|
)
|
||||||
|
@ -441,14 +441,27 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||||
while it holds the lock. The updated field isn't a field in 'defaults',
|
while it holds the lock. The updated field isn't a field in 'defaults',
|
||||||
so update_or_create() shouldn't have an effect on it.
|
so update_or_create() shouldn't have an effect on it.
|
||||||
"""
|
"""
|
||||||
|
lock_status = {'has_grabbed_lock': False}
|
||||||
|
|
||||||
def birthday_sleep():
|
def birthday_sleep():
|
||||||
time.sleep(0.3)
|
lock_status['has_grabbed_lock'] = True
|
||||||
|
time.sleep(0.5)
|
||||||
return date(1940, 10, 10)
|
return date(1940, 10, 10)
|
||||||
|
|
||||||
def update_birthday_slowly():
|
def update_birthday_slowly():
|
||||||
Person.objects.update_or_create(
|
Person.objects.update_or_create(
|
||||||
first_name='John', defaults={'birthday': birthday_sleep}
|
first_name='John', defaults={'birthday': birthday_sleep}
|
||||||
)
|
)
|
||||||
|
# Avoid leaking connection for Oracle
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
def lock_wait():
|
||||||
|
# timeout after ~0.5 seconds
|
||||||
|
for i in range(20):
|
||||||
|
time.sleep(0.025)
|
||||||
|
if lock_status['has_grabbed_lock']:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
|
Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
|
||||||
|
|
||||||
|
@ -457,8 +470,8 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||||
before_start = datetime.now()
|
before_start = datetime.now()
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
# Wait for lock to begin
|
if not lock_wait():
|
||||||
time.sleep(0.05)
|
self.skipTest('Database took too long to lock the row')
|
||||||
|
|
||||||
# Update during lock
|
# Update during lock
|
||||||
Person.objects.filter(first_name='John').update(last_name='NotLennon')
|
Person.objects.filter(first_name='John').update(last_name='NotLennon')
|
||||||
|
@ -469,5 +482,5 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||||
|
|
||||||
# The update remains and it blocked.
|
# The update remains and it blocked.
|
||||||
updated_person = Person.objects.get(first_name='John')
|
updated_person = Person.objects.get(first_name='John')
|
||||||
self.assertGreater(after_update - before_start, timedelta(seconds=0.3))
|
self.assertGreater(after_update - before_start, timedelta(seconds=0.5))
|
||||||
self.assertEqual(updated_person.last_name, 'NotLennon')
|
self.assertEqual(updated_person.last_name, 'NotLennon')
|
||||||
|
|
Loading…
Reference in New Issue