Opened 16 years ago

Closed 16 years ago

#5632 closed (invalid)

Problems with DB objects on a multithreaded scenario

Reported by: claudio.marinozzi@… Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: multi thread db
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Discussion topic that started here in Django Developers

There are some critical functions like get_or_create, create, delete, add, remove, etc. that if used in a multithreaded scenario could be crash or "damage data" (some samples in the discussion above) when working on same DB-data, or even not, at the same time.

These operations should be serialized (mutexed) or something like that.

I attach a diff file containing the quick, but working, solution. It's a decorated function used on those critical functions that does the mutex thing. Maybe the decoration should be added to some other functions too. Still don't know Django that good.

Attachments (3)

dbmultithreaded.diff (5.8 KB ) - added by claudio.marinozzi@… 16 years ago.
diff created with Django on Trunk at h12pm Italy time
dbmultithreaded2.diff (5.9 KB ) - added by teepark 16 years ago.
dbmultithreaded3.diff (6.3 KB ) - added by teepark 16 years ago.
based on SVN trunk r7364

Download all attachments as: .zip

Change History (9)

by claudio.marinozzi@…, 16 years ago

Attachment: dbmultithreaded.diff added

diff created with Django on Trunk at h12pm Italy time

comment:1 by James Bennett, 16 years ago

Patch needs improvement: set

comment:2 by Erin Kelly, 16 years ago

Please use the syntax "get_or_create = mutex(get_or_create)" for your decorators rather than the "@mutex" syntax. The reason for this is that the @ syntax is not supported in Python 2.3.

Also, please don't put your name in the code. If you want to be credited for your contributions, that's fine, but the proper place for it is in the AUTHORS file. See http://www.djangoproject.com/documentation/contributing/#coding-style for more information.

On a more stylistic note, this code:

        try:
            res = func(*args, **kwargs)
        except:
            __serializer.release()
            raise
        __serializer.release()

is exactly equivalent to this:

        try:
            res = func(*args, **kwargs)
        finally:
            __serializer.release()

comment:3 by Simon G <dev@…>, 16 years ago

Has patch: set
Triage Stage: UnreviewedAccepted

by teepark, 16 years ago

Attachment: dbmultithreaded2.diff added

by teepark, 16 years ago

Attachment: dbmultithreaded3.diff added

based on SVN trunk r7364

comment:4 by anonymous, 16 years ago

Patch needs improvement: unset

sorry for the two tickets, I meant to include Claudio and myself in AUTHORS

comment:5 by teepark, 16 years ago

I don't have the necessary permission to modify/remove tickets otherwise I would remove mine.

This doesn't fix the multi-process situation - each process would just acquire it's own process-specific lock.

Also, get_or_create shouldn't be used with non-unique fields anyway (you get an AssertionError if more than one row comes up), and get_or_create in the development version catches IntegrityErrors, which will result from the unique constraint being violated by simultaneous get_or_creates.

So claudio's and my patches don't fix the whole problem, and the development version already does for sane cases. Sorry for all the unnecessary posts & patches.

comment:6 by mrts, 16 years ago

Resolution: invalid
Status: newclosed

This can be closed especially now that Malcolm has checked r8267 in.

Note: See TracTickets for help on using tickets.
Back to Top