offにする必要がある。
(1) 'ATOMIC_REQUESTS': TRUE (settings.py)
(2) デコレータ
(3)with transaction.atomic():
(1) 'ATOMIC_REQUESTS': TRUE (settings.py)
通常は、 'ATOMIC_REQUESTS': False に設定されており、autocommit=Trueのなっている為、save()等は、都度commitされる。'ATOMIC_REQUESTS': TRUEを指定されると、autocommit=Falseになり、View内で正しく処理が終了すると、全てcommitされ、view内でexceptionが発生すると全てrollbakckされる。
(2) デコレータ
クラスやメソッド単位に、autocommitを変更できる。2-1 'ATOMIC_REQUESTS': False (settings.py) --> autocommit=True
下記のデコレータを記述する事でクラスやメソッド毎にautocommit=Falseに設定できる。
1 from django.db import transaction
2 class Sample_View( TemplateView):
3 def post(self, request, *args, **kwargs):
4 context = super().get_context_data(**kwargs)
5 with transaction.atomic( using='sample_db', durable=True ):
6 sid = transaction.savepoint( using='sample_db' )
7 with transaction.atomic( using='sample_db' ):
8 model1.save( using='sample_db')
9 model2.save( using='sample_db')
10 transaction.savepoint_rollback( sid, using='sample_db' )
11 with transaction.atomic( using='sample_db', savepoint=True ) :
12 model3.save( using='sample_db')
13 model4.save( using='sample_db')
14 return render(self.request, self.template_name, context
connections[SCHEMA_ARCSDBSS].rollback()
@method_decorator(transaction.atomic( using='sample_db'), name='dispatch')
Class Sample_View( TemplateView):
or
@transaction.atomic( using='sample_db' )
def post(self, request, *args, **kwargs):
Class Sample_View( TemplateView):
or
@transaction.atomic( using='sample_db' )
def post(self, request, *args, **kwargs):
2-2 'ATOMIC_REQUESTS': True (settings.py) --> autocommit=False
下記のデコレータを記述する事でクラスやメソッド毎にautocommit=Trueに設定できる。
@method_decorator(transaction.non_atomic_requests( using='sample_db'), name='dispatch')
Class Sample_View( TemplateView):
or
@transaction.non_atomic_requests( using='sample_db' )
def post(self, request, *args, **kwargs):
(3)with transaction.atomic():
with内は、autocomitt=Falseが設定され、with内のDBアクセスは一連のトランザクションとして扱われる。
withを正常に抜けた時に、commitされ、途中で exception が発生した場合は、
rollbackされる。
入れ子の場合は、一番外側のwithを抜けた時に、commit またはrollbackされる。
【例】
mode1/2 および mode3/4のアクセスがトランザクションとして扱われている。
下記の例では、model1/2は、rollbackされ、最終的にmodel3/4のみがコミットされている。
2 class Sample_View( TemplateView):
3 def post(self, request, *args, **kwargs):
4 context = super().get_context_data(**kwargs)
5 with transaction.atomic( using='sample_db', durable=True ):
6 sid = transaction.savepoint( using='sample_db' )
7 with transaction.atomic( using='sample_db' ):
8 model1.save( using='sample_db')
9 model2.save( using='sample_db')
10 transaction.savepoint_rollback( sid, using='sample_db' )
11 with transaction.atomic( using='sample_db', savepoint=True ) :
12 model3.save( using='sample_db')
13 model4.save( using='sample_db')
14 return render(self.request, self.template_name, context
※上記、(1),(2),(3)の内、 重要なトランザクション処理は、明示的行う為に、「(3)with transaction.atomic()」を使用するのが望ましいと考えるが、更にクリティカルな処理を行う為に、connectionsのメソッドを使用して、直接制御する事も可能。
from django.db import connections
connections.set_autocommit( False)
connections[SCHEMA_ARCSDBSS].commit()connections[SCHEMA_ARCSDBSS].rollback()
※ transaction.atomic()は、connectionsのメソットを使用した上位インターフェースになっている。
0 件のコメント:
コメントを投稿