Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django transaction using multi-db

I have three database and I want to adding data to they in transactions on one request.

For example my code.

@transaction.commit_manually
def my_view(request):
    try:
        MyModel_one(...).save(using='default')
        MyModel_two(...).save(using='db_one')
        MyModel_three(...).save(using='db_two') # <-- for example we make exception here (duplicate data)
    except IntegrityError:
        transaction.rollback()
        transaction.rollback(using='db_one')
        transaction.rollback(using='db_two')
        return ...
    transaction.commit()
    transaction.commit(using='db_one')
    transaction.commit(using='db_two')
    return ...

Result:

  1. MyModel_one — data didn't saved
  2. MyModel_two — data saved (I didn't understand why)
  3. MyModel_three — data didn't save because hope error

question: Why transaction didn't work here ? What can I do to get work transaction ?

(I try to use other ways but didn't have success result) (Also I understand it's not beutiful code but very simple for understanding the problem)

Django 1.7.7 Python 2.7

Database: default — postgres db_one — mysql db_two — mysql

like image 965
kalloc Avatar asked Dec 01 '25 05:12

kalloc


1 Answers

The transaction.commit_manually decorator was deprecated in Django 1.6. You should switch to Django's new transaction management.

I don't think you need to commit transactions manually, you can nest transaction.atomic.

def my_view(request):
    try:
        with transaction.atomic(using='default'):
            with transaction.atomic(using='db_one'):
                with transaction.atomic(using='db_two'):
                    MyModel_one(...).save(using='default')
                    MyModel_two(...).save(using='db_one')
                    MyModel_three(...).save(using='db_two') # raises exception
    except IntegrityError:
        return ...
    return ...
like image 162
Alasdair Avatar answered Dec 03 '25 18:12

Alasdair