On Fri, May 8, 2015 at 5:50 PM, Carl Meyer <c...@oddbird.net> wrote:

> Hi Marc,
>
> On 05/08/2015 07:15 AM, Marc Aymerich wrote:
> > I'm using atomic requests, but one of my views needs to save a model
> > regardless of wheter the current transaction rolls back or not.
> >
> > I'm confused about how to proceed with the current autocommit behaviour.
> > Do I need to use a different db connection? or perhaps there is some way
> > of telling django to ignore autocommit for some particular block ?
>
> You'd need to use a different db connection, since what you're trying to
> do violates the very nature of a database transaction. If you were just
> trying to run some raw SQL, you could establish the separate connection
> yourself manually, but if you're trying to save a Django model, you'll
> probably need a second connection defined in your DATABASES setting.
>
> Possible alternatives:
>
> - If you're using a task queuing system (like Celery or rq), queue a
> task to perform the save; you can do this without making it conditional
> on the transaction committing, as long as your task queue is using a
> store other than your primary database (e.g. Redis or RabbitMQ). Usually
> when people do this it's unintentional and a bug (they really wanted the
> task to execute only if the current transaction committed), but in your
> case it could be a feature.
>

Yep, the thing is that I need to have this instance saved before handling
it to a worker process, the worker process uses it and if something goes
wrong on the main thread then the worker has an object that does not exists
on the database. Now I realize that I can just catch the IntegrityError and
re-save the object on the worker thread ;)

obj.pk = None
obj.save()


- Switch from ATOMIC_REQUESTS to explicit use of transaction.atomic() in
> your views, so that you can place this "no matter what" save in its own
> transaction.


I've been doing something on those lines, but now I have this corner case
which I have surouding code that needs to be wrapped up in a transaction :(

For the record, after exploring django.db I realize of 2 more alternative
ways of dealing with this situation:

1) because the connection pool is a local thread object, you can just
fireup a separate thread, so it will have fresh connections :)

t = threading.Thread(target=backend.create_log, args=args)
t.start()
log = t.join()

2) because a new connection is created for each settings.DATABASES, it is
easy to have new connections with a fake database. I've also created a
context manager for that

from django import db
from django.conf import settings as djsettings

class fresh_connection(object):
    def __init__(self, origin, target):
        self.origin = origin
        self.target = target

    def __enter__(self):
        djsettings.DATABASES[self.target] =
djsettings.DATABASES[self.origin]
        # Because db.connections.datases is a cached property
        db.connections = db.utils.ConnectionHandler()

    def __exit__(self, type, value, traceback):
        db.connections[self.target].close()
        djsettings.DATABASES.pop(self.target)


with fresh_connection('default', 'other_default'):
    log = backend.create_log(*args, using='other_default')
    log._state.db = 'default'


>
> Carl
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/554CDB37.7060503%40oddbird.net
> .
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Marc

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CA%2BDCN_tc946DGihEAu1xqJOgHR8U4td%2Bb-TPS7zu8xAs1jQnnA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to