2017-10-12 6 views
0

私たちのアプリケーションでは、いくつかのエンティティの変更を監査する必要があり、JaVersを使用することを考えています。私はJaVersによって提供された監査データを尋問するためのサポートが好きです。 Hibernate Enversはよく見えますが、同じDBにデータを格納します。 - パフォーマンスへの影響を最小限に抑えるための JaVersでの非同期監査

  • 異なるDBに格納し、監査データ - パフォーマンス上の理由だけでなく
  • 私の知る限り見ることができるようにJaVers

    • 非同期ロギング:ここ

      は私の要件です上記のために設計されていませんが、上記を達成するために適応するように思われる。方法は次のとおりです。

      • JaVersでは、実際には別のDBにデータを格納することができます。あなたは本当に任意のDBへの接続を提供することができます。それはどのように意図されているのではなく、それは動作します。以下のコードは、(任意のDBへの接続を提供することができるされたConnectionProviderに注意):

      '

      final Connection dbConnection = 
            DriverManager.getConnection("jdbc:mysql://localhost:3306/javers", "root", "root"); 
      
      ConnectionProvider connectionProvider = new ConnectionProvider() { 
          @Override 
          public Connection getConnection() { 
           //suitable only for testing! 
           return dbConnection; 
          } 
      }; 
      JaversSqlRepository sqlRepository = SqlRepositoryBuilder 
            .sqlRepository() 
            .withConnectionProvider(connectionProvider) 
            .withDialect(DialectName.MYSQL).build(); 
      
      • 非同期がJaVersの実行を移動させることによって達成することができるスレッド/エグゼキュータにコミット。その課題は、実行に時間がかかりすぎると、ログに記録される前にオブジェクトが変更される可能性があるということです。
        • オブジェクトのスナップショットを作成して(JSONなどにシリアル化して)、スレッドに渡してログに記録する方法があります。
        • 現在のスレッドの違いを処理したJaversリポジトリのカスタム実装を提供してから、別のスレッドで永続化するSnapshotオブジェクトを渡します。このようにして、アプリケーションスレッドでDBからの読み取りのみを行い、監査スレッドでは(一般的にはコストパフォーマンスの高いパフォーマンス)を記述します。

      質問:私はここで何を

      • をしないのですか?これは動作しますか?
      • JaVersは、オブジェクトのスナップショットを作成して別のスレッドに移動できるかどうかをサポートしていますか?それは内部的にどこかで行うので、おそらくそれは私たちが使うことができるものです。

      JUST FYI:質問に関連するが、ここではない私は考えることができる他のいくつかの課題があり、どのように私はそれらを解決するために計画しています:

      • により、同じトランザクション内で監査を行っていないにトランザクションが失敗したように、監査ロールバックは複雑になります。したがって、正常にコミットされたオブジェクトだけを監査する必要があります。私はafterTransactionCompletionを聞いて、そのトランザクションによって更新されたオブジェクトだけを聞いて、Hibernate Interceptorを使ってそれを行うつもりです。
      • 遅延ロードされたオブジェクトの場合、トランザクションが完了した後にアクセスしようとすると、遅延ロードされたプロップにアクセスできなくなることがあります(セッションが閉じられている可能性があります) - これを修正する方法はわかりませんが、ほとんどの小道具を熱望していると思うので問題にはならないかもしれません。

    答えて

    1

    興味深い質問です。 最初にdémenti。すべてのJaVersコアモジュールは、アプリケーションデータから監査データを分離するように設計されています。前述のとおり、ユーザーはJaVersで使用するConnectionProviderを提供します。それはあなたが望むどんなデータベースでもかまいません。

    複数のDBで使用するように設計されていないものは、SQL用のSpring統合モジュールです(javers-spring-jpaおよびjavers-spring-boot-starter-sql)。彼らはアプリケーションとJaVersのための同じDBので、最も一般的なシナリオをカバーします。

    あなたは非同期コミットが不足していることは間違いありません。幸い、リポジトリを変更せずにJaversCoreにしか実装できません。

    APIは、次のようになります。

    CompletableFuture<Commit> javers.commitAsync(..., Executor); 
    

    まず、Javersは、それが現在のスレッドで行うことができるので、それは速いですが、ユーザーのオブジェクトのスナップショットを取得します。

    次に、DB読み取り(最新のスナップショットのロード)とDB書き込み(新しいスナップショットの挿入)を非同期で実行できます(指定されたExecutorに送信されます)。

    前述のとおり、DBトランザクションへの新しいアプローチが必要です。 Commit Withdrawal機能を実装する予定であるため、メインDBロールバック後にJaVersのコミットを取り消すことができます。 https://github.com/javers/javers/issues/588

    +0

    ありがとうございます。もっと興味深いものにするために、Java 7も使用していますが、あまりにも早く変更することができるかどうかは疑問です(10年以上前のかなり複雑なアプリケーションなので、変更は非常に遅くなります)。以前のバージョンでその変更を行うことは可能ですか?また、実際に非同期サポートを追加する予定ですか? – Stef

    +0

    最新バージョンのJaVersを利用できるようになると、古いバージョンのJaVersにコードを移植することができます。 – Stef

    +1

    JaVers 2.9.2(Java 7と互換性のある最新バージョン)は開発しません。私たちは2.9.2から多くの変更とリファクタリングを行いました。そのため、JaVers 3.6から2.9に機能を戻すことは悪夢になります。 async commitについての計画はありません。commit withdrawal、おそらく1月後にそれを行うことができると思います –