ビジネスを理解していない、私は別のブログ読んでお勧めのMySQL 4トランザクション分離レベルを
まず、シーンの話
擬似コードを書き留め
V1バージョン
サービスレベルのコード
1 パブリック クラスDemoService { 2 @Autowired 3。 プライベートDemoTask demoTask; 4 @Autowired 。5 プライベートDemoDao demeDao; 6 。7 @Transactional 8。 公共 ボイド保存(){ 9。 のSystem.out.println( "実行開始トランザクション" ); 10 リスト<DemoEntity >リスト= 新しい新規のArrayList(); //は、長いリストの長さを仮定しました。 。11 demeDao.saveAll(一覧); // データのINSERTロット 12がある のSystem.out.println( "プログラムへの非同期開始" ); 13 demoTask.task(); 14 のSystem.out.println( "トランザクションが終了する" ); 15 } 16 }
非同期タスク
1 @Component 2 パブリック クラスDemoTask { 3。 @Autowired 4。 プライベートDemoDao demeDao; 5 6。 @Async 7。 公共 ボイドタスク(){ 8。 試し { // デモを容易にするために、しばらくの間、スリープ状態に現在の非同期スレッドをさせ 9。 のThread.sleep(1,000 ) ; 10 } キャッチ(InterruptedExceptionあるE){ 11。 e.printStackTrace(); 12である } 13が 一覧<DemoEntity>一覧= demeDao.findAll(); 14 //擬似コードは、この非同期タスクは、前のステップの提出の結果に基づいて、コンピューティングの多くを行うことであろう。 15 のSystem.out.println( "非同期トランザクション処理" ); 16 } 17 }
印刷SQLの場合。
トランザクション実行が開始 2 SQL INSERT INTO ....... 。3 SQL INSERT INTO ....... 。4 SQL INSERT INTO ....... 。5 SQL INSERT INTO ....... 。6 。 ....... 。7 SQL INSERT INTO ....... 。8 SQL INSERT INTO ....... 。9 SQL INSERT INTO ....... 10 SQL INSERT INTO ...... 。 11 トランザクションが完了した 12処理非同期トランザクションを
ログインは問題なく、右、上に示した印刷しますか?
しかし、結果はそうではありませんが、この下に。
トランザクション実行開始
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
........
トランザクションが終了します
非同期トランザクション処理
........
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
ええと(⊙o⊙)...なぜSAVEALL()メソッドを非同期効果が発生する理由は?
V2バージョン
パブリック クラスDemoService { @Autowired プライベートDemoTask demoTask。 @Autowired プライベートDemoDao demeDao。 // @トランザクション 公共 のボイド(保存){ System.out.println( "トランザクションを開始実行" ); 一覧 <DemoEntity>リスト= 新しい新しいのArrayList(); // 長いリストの想定長さ。 demeDao.saveAll(一覧); // データのINSERTロット のSystem.out.println( "プログラムは、非同期実行を開始します" ); demoTask.task(); System.out.println( "トランザクションが終了します" ); } }
コードのキー行がコメントアウトされて @Transactional ログは、印刷を見続けます
トランザクション実行開始
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
........
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
トランザクションが終了します
非同期トランザクション処理
ええと、同期されるように、はい、 @Transactionalが 原因になっているSAVEALL()メソッドは、我々はそのソースコードを研究するための非同期の時間になってきた理由として、非同期の鍵となっています。
それが何本論文の焦点でありますか?上読みます
第二には、コードの魔法行から始まります
再びコードを貼り付けます。
// -サービスビジネス層 パブリック クラスDemoService { @Autowired プライベートDemoTask demoTask。 @Autowired プライベートDemoDao demeDao。 @Transactional 公共 のボイドの保存(){ System.out.println( "トランザクションを開始実行" ); 一覧 <DemoEntity>リスト= 新しい新しいのArrayList(); // 長いリストの想定長さ。 demeDao.saveAll(リスト); //データの多くは、INSERT、非同期実行INSERT のSystem.out.println( "プログラムの開始は、非同期実行" ); demoTask.task(); System.out.println( "トランザクションが終了します" ); } } // などの非同期タスク @Component パブリック クラスDemoTask { @Autowired プライベートDemoDao demeDao。 非同期@ //非同期実行 公共 のボイドタスク(){ 試み { // しばらくの間、スリープ状態に現在の非同期スレッドせ、プレゼンテーションを容易にするため のThread.sleep(1000); } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } リスト <DemoEntity> = demeDao.findAllリスト(); // 擬似コード、これは送信前のステップの演算結果に応じて非同期タスクの多くを行います。 System.out.println(「非同期トランザクション処理」)。 } }
赤いマーク重要なコード最初のノート
最初は、 @Transactional 原因 demeDao.saveAll(一覧); // データのINSERTロット SAVEALL()メソッドは非同期実行となっています。
第二 @Asyncは タスク()メソッドは、非同期です。
ことは明らかであるために ()が保存 トランザクションで、 タスク() メソッドは、別のトランザクションです。これらは、ID、SQL業務を確認するには、この行を実行することができると信じていない、説明していない TRANSACTION_ISOLATIONを示し 、あなたがはっきりとその実際に二つの別々のトランザクションが表示されます。
次に、データの束を保存するシーン、サービス層save()メソッドの上にストローク、タスク()メソッドは、結果を保存する()メソッド、操作の次の段階セーブ単離されます。
この問題は、(保存、出てきた時間)とタスク()メソッドは、データを保存する(コミット)を保存()トランザクションのコミットを確保するために、我々は二つのトランザクションを制御しないか、非同期であり、タスク()問題に確認することができます(最新のメソッドの保存結果)を保存するには?
PostgreSQLデータベースを使用しているため、デフォルトでは、読み取りコミット分離レベルがコミット読み込まれます。読み取りコミット意味は、トランザクションのコミットの保存()メソッドは、あなたが新たに挿入されたタスク()メソッドでは、テーブルのデータを読み取ることができたときに言うことです。だから今タスク非同期メソッドの実行前にトランザクションを提出するには、Save()メソッドを確保する方法の質問が。
そして、あなたは、トランザクションのコミットのタイミングということを理解する必要があります。様々なデータベースでは、トランザクションはデフォルトで自動的に提出され、彼らは手動でトランザクションのコミットを制御する方法について話すことはありません。
取引のタイミングが提出:トランザクションが成功したすべてのSQLの実装を完了すると、トランザクションが自動的に提出されます。
あなたは上記の問題を理解していれば、その行は魔法のコードが何であるかを考えることは困難です。
1 パブリック クラスDemoService { 2 @Autowired 3。 プライベートDemoTask demoTask; 4 @Autowired 。5 プライベートDemoDao demeDao; 6 。7 @Transactional 8。 公共 ボイド保存(){ 9。 のSystem.out.println( "実行開始トランザクション" ); 10 リスト<DemoEntity >リスト= 新しい新規のArrayList(); //は、長いリストの長さを仮定しました。 11 demeDao.saveAll(一覧); // データのINSERTロット 12 demoDao.countByXXX(); //これは、コード魔法のラインでは、実際には、唯一のSQLでクエリを実行する必要があります 13 System.out.println( "プログラムに非同期開始" ); 14 demoTask.task(); 15 のSystem.out.println( "トランザクションが終了する" ); 16 } 17 }
コード行は、上記の魔法のラインであるだけで(厳密にこれを話すことは最も簡単にはxxxtableからのカウント(*)を選択することで、ちょうど選択データを挿入カバーしなければならない)にselect文を実行しています。なぜ?
SQLテーブルでも非同期select文のSQLの前に、それがされると言うことですつまり、最新のスナップショットを生成するためのコード行を変更しますので、ブロックされた]を選択するまで、ここで @Transactionalが 原因 SAVEALL(リスト)は 非同期で実行完全な。現在のスレッドが(springbootのために、データベースの現在の情勢である)の実装をダウンしていきます。
次のようにコードのその魔法のラインと、ログが印刷されています。
トランザクション実行開始
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
........
挿入SQL .......
挿入SQL .......
挿入SQL .......
挿入SQL .......
トランザクションが終了します
非同期トランザクション処理
上記の取引と組み合わせることで継続する時間をコミットし、(保存)取引の方法、これが終了し、それが提出(コミット)しなければなりません。
トランザクションのようなタスク()メソッドがスムーズだけデータを参照するために挿入することができます。
コード魔法何このソリューションのラインに加えて?はい、トランザクションを手動制御に提出されます。トランザクションはトランザクションを手動で制御するバック手動制御手段を巻いているので、当然のことながら、事務の手動制御は、推奨されません。いかなるロールにも何の意味がトランザクションをバックアップしません。
1(「トランザクション開始」)を実行// 開いている業務を 2 // ビジネスコード 3の実行(「コミット」)// トランザクションをコミット
第三に、トランザクションとMySQL PostgreSQLの違い
私は別の記事のブログを読むことができ、トランザクションを理解していない:MySQLの4トランザクション分離レベル
PostgreSQLの総務とMySQLの違いは、PostgreSQLのデフォルトのトランザクション分離レベルが読み取りコミットされていることで、MySQLのデフォルトのレベルは反復可能読み取りです。
その内部機構がロック、MVCC、現在の読み取りのスナップショットを読み取り、上のようになど、同じです。
第四に、拡張
トランザクション分離レベルの場合に:反復可能読み取り、2つの非同期トランザクションを制御する方法の順序をコミットします。
あなたが使用している場合:ReentrantLockのか、同期のコースを、私たちはこの問題を解決することができます。
コメントは興味を議論することができます。
早期の心を忘れませんでした
間違った場所には、メッセージ補正を残してください場合。
:元は容易ではありません、元のアドレスを明記してくださいhttps:////www.cnblogs.com/hello-shf/p/12543766.htmlを