Spring事務原理を深く理解する

6312 ワード

事務の基本原理
Spring事務の本質はデータベースの事務サポートであり、データベースの事務サポートがないと、springは事務機能を提供できません.純JDBC操作データベースについては、事務を使いたいので、以下の手順で行うことができます.
  • 1、接続Connection con=DriverManager.get Connectionを取得する()
  • 、ビジネスコン.set AutoCommt(true/false)をオープンする.
  • 、CRUDを実行する
  • 、事務/ロールバック事務con.co mmit()/con.rollback();
  • 、接続conn.closeを閉じる().
  • Springの事務管理機能を使って、手順2と4のコードを書かなくてもいいです.Spirngで自動的に完成します.じゃSpringはどうやって私達が書いたCRUDの前と後で事務と事務を始めますか?この問題を解決すれば、Springの事務管理を全体的に理解することができます.以下、簡単に紹介します.注釈の方法は例です.
  • 1、プロファイルは注釈駆動を開始し、関連するクラスおよび方法は注釈@Transactionalによって識別される.
  • 、springは起動時に関連するbeanを解析します.この時に関連する注釈を持つ種類と方法を確認して、これらの種類と方法のために代理を生成し、@Transactionの関連パラメータに基づいて関連する配置を注入します.このように代理で関連する事務を処理しました..
  • 、本物のデータベース層のトランザクションの提出とロールバックは、binlogまたはredo logによって達成される.
  • Spring事務の伝播属性
    spring事務の伝播属性とは、複数の事務が同時に存在する場合に、springがどのようにこれらの事務を処理すべきかを定義する行為である.これらの属性はTransactionDefinitionにおいて定義され、具体的な定数の説明は下表を参照してください.
    定数
    説明
    PROPAAGATION_REQUIRED
    現在の事務をサポートしていますが、現在の事務がない場合は、新しい事務を作成します.これは最も一般的な選択であり、Springのデフォルトの事務の伝播でもある.
    PROPAAGATION_REQUIRES_NEW
    新しい事務を作って、現在の事務があれば、当面の事務を保留します.新規の事務は保留された事務と何の関係もありません.独立した二つの事務です.外部事務が失敗して転覆した後、内層事務の実行を繰り返すことができなくなりました.
    PROPAAGATION_SUPPORTS
    現在の事務をサポートします.現在は事務がない場合は、非事務で行います.
    PROPAAGATION_MANDATORY
    現在の事務をサポートしていますが、今は仕事がないと異常を投げます.
    PROPAAGATION_NOT_SUPPORTED
    非事務方式で操作を行い、現在事務があれば、当面の事務を保留する.
    PROPAAGATION_NEVER
    非事務的に実行し、現在事務がある場合は異常を投げます.
    PROPAAGATION_NESTEP
    イベントのトランザクションが存在する場合は、ネストされたトランザクションで実行されます.イベントトランザクションがない場合は、REQUID属性で実行されます.これは単独の事務を使っています.この事務はロールバックできる保存点が複数あります.内部事務のロールバックは外部事務に影響を与えません.DataSourceTransation Manager事務マネージャだけに効果があります.
    データベース分離レベル
    隔離レベル隔離レベルの値による問題
  • Read-Unicomitted:汚読の原因となる
  • Read-Comitted:汚い読書を避けるために、繰り返して読んではいけません.
  • Repeable-reed:汚い読みを避けて、繰り返して読んではいけません.幻読みを許可します.
  • Serializable:シリアル化して読み、事務は一つずつ実行して、汚い読み、繰り返してはいけない読み、幻読みを回避しました.実行効率が遅く、慎重に使用する.
    用語の解釈
  • 汚読:一つの事務はデータを削除しましたが、提出していません.もう一つの問題は未提出のデータを読み取ることができます.最初の仕事がこの時にロールバックしたら、二つ目の仕事は汚いデータを読みました.
  • 重複して読んではいけません.一つの事務では2回の読み取り操作があり、1回目の読み取りと2回目の操作の間に、もう一つの事務でデータが修正されています.この場合、2回目に読み取ったデータは一致しません.
  • 幻読み:第一の事務は一定範囲のデータを大量に修正し、第二の事務はこの範囲でデータを追加します.この場合、第一の事務は新規データに対する修正をなくします.
  • まとめ:
  • 隔離レベルが高いほど、データの完全性と整合性は保証されますが、同時性能に対する影響も大きいです.
  • ほとんどのデータベースのデフォルトの分離レベルは、例えばSql Server、Oracle
  • です.
  • 少数データベースのデフォルトの分離レベルは、例えば、MySQL InnoDB
  • です.
    Springでの隔離レベル
    定数解釈
  • ISO LATION_DEFAULT:Platofrom Transation Managerのデフォルトの分離レベルで、データベースのデフォルトの事務分離レベルを使用します.他の四つはJDBCの隔離レベルに対応しています.
  • ISO LATION_READ_UNCOMMITTED:これは最も事務レベルが低いので、他の事務を担当しています.この事務未提出のデータを見ることができます.このような隔離レベルは汚い読みを生じ、繰り返して読んではいけません.
  • ISO LATION_READ_COMMITTED:事務修正のデータを提出してから他の事務に読み込むことができます.もう一つのトランザクションは、当該トランザクションが未送信のデータを読み取ることができません.
  • ISO LATION_REPEATABLE_READ:このような事務分離レベルは汚い読みを防止できます.繰り返して読んではいけません.でも幻像が出て読むかもしれません.
  • ISO LATION_SERIALIZABLE:これは最も高い代価を払うのですが、最も信頼できる事務隔離レベルです.トランザクションは順次実行されるように処理される.
  • トランザクションの入れ子
    上記の理論的知識の下地を通して、データベース事務とspring事務のいくつかの属性と特徴を大体分かりました.次にいくつかのネストトランザクションの場面を分析して、spring事務の伝播のメカニズムを深く理解します.
    外部事務Service AMethod A()が、内部層Service BMethod B()を起動すると仮定する.
     MethodA(){
        MethodB();
     }
    
    PROPAAGATION_REQUIRED(springデフォルト)ServiceB.methodB()のトランザクションレベルがPROPAGATION_REQUIREDと定義されている場合、ServiceA.methodA()を実行すると、既にスプリングが開始されています.ServiceB.methodB()を呼び出して、ServiceB.methodB()は、ServiceA.methodA()が動作しているオフィスの内部を見て、新たなトランザクションを開始しません.
    もしServiceB.methodB()が運行している時に自分が事務中でないことを発見したら、彼は自分のために事務を割り当てます.
    このように、ServiceA.methodA()またはServiceB.methodB()内のどこかに異常が発生し、事務がロールバックされる.
    PROPAAGATION_REQUIRES_NEW
    例えば、私たちが設計したServiceA.methodA()の事務レベルはPROPAGATION_REQUIREDで、ServiceB.methodB()の事務レベルはPROPAGATION_REQUIRES_NEWです.ServiceB.methodB()に実行されると、ServiceA.methodA()の事務は保留され、ServiceB.methodB()は新しい事務を開始し、ServiceB.methodB()の事務が完了するまで待機してから、それは継続して実行される.
    彼とPROPAGATION_REQUIREDの事務の違いは、事務のロールバックの程度にある.ServiceB.methodB()は新しい事務ですから、二つの異なる事務があります.ServiceB.methodB()が既に提出されている場合、ServiceA.methodA()は失敗してロールバックし、ServiceB.methodB()はロールバックしない.ServiceB.methodB()が失敗したらロールバックします.もし彼が投げた異常がServiceA.methodA()によって捕まえられたら、ServiceA.methodA()事務はまだ***に提出する可能性があります.
    PROPAAGATION_SUPPORTSServiceB.methodB()の事務レベルがPROPAGATION_SUPPORTSであると仮定すると、ServiceB.methodB()に実行されたときに、ServiceA.methodA()が一つのトランザクションを開いていることが発見された場合、現在の事務に参加し、ServiceA.methodA()がトランザクションを開いていないことが発見された場合、自分も事務を開始しない.このような場合、内部法の事務性は、最外層の事務に完全に依存します.
    PROPAAGATION_NESTEP
    現在の状況は複雑になりました.ServiceB.methodB()のトランザクション属性はPROPAGATION_NESTEDに構成されています.この時、両者の間ではどう協力しますか?ServiceB#methodBrollbackであれば、内部事務(ServiceB#methodB)は、その実行前のSavePointにロールバックし、外部事務(すなわちServiceA#methodA)は、次の2つの処理形態があり得る.
  • a、捕獲異常、異常分岐論理
  • を実行する.
        voidmethodA() {
            try {
                ServiceB.methodB();
            } catch (SomeException) {
                //       ,   ServiceC.methodC();
            }
        }
    
    このような方法は、ネストされたトランザクションの最も価値のあるところであり、分岐実行の効果を発揮し、ServiceB.methodBが失敗したらServiceC.methodC()を実行し、ServiceB.methodBが実行前のSavePointにロールバックしているので、汚れたデータは発生しない(この方法は未実行に相当)、このような特性は、特定の特殊な業務において使用されてもよい.PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWはいずれもこのようなことができません.
  • b、外部事務のロールバック/提出
  • コードが何も修正されていない場合、内部事務(ServiceB#methodB)rollbackは、まずServiceB.methodBをその実行前のSavePointにロールバックさせ、外部事務(ServiceA#methodA)は、具体的な構成に基づいて、自分がcommtであるか、またはrollbackであるかを決定する.
    他の三つの事務伝播属性はほとんど使えません.ここでは分析しません.
    締め括りをつける
    プロジェクトの中で事務を使う必要があるところに対して、開発者はやはりspringのTransaction Callbackインターフェイスを使って事務を実現することを提案します.spring事務の注釈を盲目的に使わないでください.もし必ず注釈を使うならば、spring事務の伝播メカニズムと隔離レベルについて詳しく知る必要があります.