What would you say about checking which CRUD operations were executed 
within atomic() call (in order to serialize them and save into a special 
model for databases which don't support this functionality) ? Is it 
realistic? 

What I mean by that is that when you do:

from django.db import transaction

with transaction.atomic():
    MyModel.objects.create(field=123)

then the generated SQL is something like

BEGIN;
INSERT INTO mymodel values (123);
COMMIT;

However, if the database doesn't support the TPC functionality, the SQL 
would have to be slightly different, say:

BEGIN;
INSERT INTO prepared_transactions (txn_id, model, operation, params) values 
('foo', 'MyModel', 'create', '{field:123}');
COMMIT;

But on the other hand, if the database does support that, it could be 
'normal', i.e.:

BEGIN;
INSERT INTO mymodel values ( ... )
BEGIN TRANSACTION 'foo';
(no COMMIT)

If it is not possible to trace the CRUD operations, would it be easier to 
introduce a slightly different syntax, say ...

from django.db import prepare_distributed:

with prepare_distributed('foo') as prepare:
    prepare.add_operation(MyModel.objects.create, {'field': 123})

After all, it's not like the developer doesn't know whether he's doing a 
distributed transaction or not.. 
 
As for making the atomic() more complex, I don't think that it would be 
significantly hard. The distributed transaction isn't really *that* 
different - it's just calling PREPARE TRANSACTION 'foo' (without calling 
COMMIT). I thought that the Atomic class could simply have some kind of 
inner method hooks. The default class could then implement those:

class Atomic(ContextDecorator):
    def _commit_wrapper(self, connection):
        return connection.commit()

but the Two phase could do it differently:

class TwoPhaseAtomic(Atomic):
    def _commit_wrapper(self, connection):
        return 
connection.prepare_distributed(self.distributed_transaction_id);

Of course, the prepare_distributed call would create models in the special 
table if the database wouldn't support the functionality and call regular 
commit() at the end, or call appropriate command otherwise - so this seems 
like the easiest thing to do. The problem that I haven't figured out yet 
would be to trace the instances being saved / created / etc ..

W dniu czwartek, 1 grudnia 2016 14:54:27 UTC+1 użytkownik Florian Apolloner 
napisał:
>
>
>
> On Thursday, December 1, 2016 at 2:04:53 PM UTC+1, Aymeric Augustin wrote:
>>
>> The person who will write and test that code has all my sympathy :-) 
>>
>
> I'll second that, I have no idea how Aymeric managed to keep his sanity 
> while rewriting the transaction code :D 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0a95bc57-d1d2-491f-9ce6-8d7956be2954%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to