2022年1月31日月曜日

Django トランザクション処理 ( transaction.atomic)

トランザクション処理を有効にするには、下記の3つの方法のいづれかで、autocommitを
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に設定できる。

     @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):

 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のみがコミットされている。

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


※上記、(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のメソットを使用した上位インターフェースになっている。







2022年1月18日火曜日

シャットダウン時の後処理 (shutdown)

# vi /etc/systemd/system/drop.service [Unit] Description= stop httpgwd DefaultDependencies=no Before=shutdown.target RefuseManualStart=true ...