Currently you cannot do this:

from django.db import connection
connection.xid()  # or any other TPC method

Adding implementations of TPC methods in BaseDatabaseWrapper() that simply 
forward to the underlying connection object is the first step for a database 
agnostic implementation in Django.

For the high level API, here’s one possibility:

# entering the block calls .xid(format_id , global_transaction_id , 
branch_qualifier) and .tpc_begin(xid)
with transaction.atomic2(format_id , global_transaction_id , branch_qualifier) 
as prepare: 

    # run statements


    # check if others are ready to commit
    # raise an exception to abort

# exiting the block calls .tpc_commit() or .tpc_rollback() depending on whether 
there’s an exception

I’m proposing a separate context manager because I’m worried about increasing 
again the complexity of transaction.atomic. There will be a significant amount 
of duplication between the two implementations, though.

The proposal above doesn’t account for recovery: .tpc_recover(), 
.tpc_commit(xid), .tpc_rollback(xid). I’m not sure what recovery of a two phase 
transaction is and I can’t say if it needs to be supported in the API.

Also I didn’t talk about savepoints. I assume they can be supported like in 
regular transactions.

I hope this helps,


> On 1 Dec 2016, at 12:27, Mateusz Mikołajczyk <mikolajczyk.mate...@gmail.com> 
> wrote:
> Hello, fellow devs.
> I have been googling intensively in order to see whether somebody already 
> raised such issue, but so far I have been unsuccesful. Therefore, trembling 
> on my legs, I decided to write to the devlist as suggested in the docs.
> I am trying to extend the atomic decorator / context statement in order to do 
> 'prepare transaction \'foo\'' rather than usual 'commit' on succesful 
> transaction. It is, however, not the usual scenario where django would talk 
> to multiple databases. What I have in mind is a bunch of microservices, one 
> of them which would be django application. Therefore django app would be 
> talking to the external transaction manager which would then take care of 
> executing the appropriate transactions inside of each microservice.
> I suppose that after a bunch of hacking I could implement this with some 
> monkey patching of the original atomic() code but it clearly is not the way 
> to go.
> I then started to think how this could be done database-agnostic way. I know 
> that PostgreSQL supports this with 'prepare transaction' statement, but I 
> suppose that other databases have different syntax for this kind of behaviour 
> and some don't support this feature at all. Therefore I thought that in e.g. 
> SQLite3 (or other database which doesn't support this natively), this 
> behavior could be 'emulated'. Therefore I thought of the following pseudocode:
> ```
> with transaction.atomic(commit_hook=lambda connection: 
> connection.prepare_transaction('foo'))
> OR
> with transaction.atomic(prepare_transaction='foo')
> ```
> When you would do CRUD operations they would be instead serialized inside a 
> special table, and then, after issuing another command, say ..
> from django.db import transaction
> transaction.commit_prepared('foo')
> they would be applied using regular 'atomic' call. (or.. I don't know, Django 
> could raise an IntegrityError if the database doesn't support distributed 
> transactions and the code would try to execute them)
> Do you think that this is realistic or is it a wrong approach to the subject?
> kind regards,
> -- 
> 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 
> <mailto:django-developers+unsubscr...@googlegroups.com>.
> To post to this group, send email to django-developers@googlegroups.com 
> <mailto:django-developers@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-developers 
> <https://groups.google.com/group/django-developers>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/8d358e52-591d-4b9b-8c11-882e6a2ac80d%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/8d358e52-591d-4b9b-8c11-882e6a2ac80d%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

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 
For more options, visit https://groups.google.com/d/optout.

Reply via email to