@Transactionalロールバックの問題(ネスティング、キャッチしてみてください)

トランザクションにエラーがある場合は春のトランザクションのアノテーション@Transactionalは原子性を保証することができ、全体のトランザクションが保証をロールバックすることができますが、トライキャッチまたはトランザクションのネストしたトランザクションのロールバックが失敗することがあります。テスト波。

レディ

2つのテーブルを構築し、2つのアナログデータ操作

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `age` smallint(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

テスト

順列と組み合わせ理論、我々は4種類のテスト:入れ子にすることなく、1、なしトライキャッチ; 2、キャッチを試みる、ネスティングなし; 3、無トライキャッチ、ネストされた; 4、両方。

最も簡単なテスト

我々は単に@Transactional場合、トランザクションは通常のロールバックすることができますか?

    @GetMapping("/saveNormal0")
    @Transactional
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new RuntimeException();
    }

トランザクション内でのRuntimeExceptionエラーを報告した場合、トランザクションはロールバックすることができます。

    @GetMapping("/saveNormal0")
    @Transactional
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new Exception();
    }

トランザクション内で例外エラー(非のRuntimeExceptionエラー)を報告した場合、トランザクションはロールバックすることはできません。

    @GetMapping("/saveNormal0")
    @Transactional( rollbackFor = Exception.class)
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new Exception();
    }

エラーが例外(以外のRuntimeException)である場合、プラスrollbackFor = Exception.classパラメータもロールバックを達成することができます。

結論1:@Transactionalの場合は、あなたがそれ以外のRuntimeExceptionエラーロールバックを確認したい場合は、あなたがrollbackFor = Exception.classパラメータを追加する必要があり、のRuntimeExceptionエラーロールバックを保証することができます。

キャッチインパクトを試してみてください

ブロガー多くの場合は、テストの結果、この事は、それ自体では効果がありませんキャッチしてみてくださいロールバックすることが判明した後、結論はまだ保持しています。例外は@Transactionalことができるだけかどうかをキャッチしてみてください、知覚影響を受けること。エラーは、それが役割を担うことができるポイントに知覚できる側面がスローされた場合。

    @GetMapping("/saveTryCatch")
    @Transactional( rollbackFor = Exception.class)
    public void saveTryCatch() throws Exception{
        try{
            int age = random.nextInt(100);
            User user = new User().setAge(age).setName("name:"+age);
            userService.save(user);
            throw new Exception();
        }catch (Exception e){
            throw e;
        }
    }

例えば、ロールバック上のコードの上記部分。

    @GetMapping("/saveTryCatch")
    @Transactional( rollbackFor = Exception.class)
    public void saveTryCatch() throws Exception{
        try{
            int age = random.nextInt(100);
            User user = new User().setAge(age).setName("name:"+age);
            userService.save(user);
            throw new Exception();
        }catch (Exception e){
        }
    }

しかし、それはエラーがインターネットをスローし続けていないキャッチすると、エラーを削減するために知覚することができない、処理できない場合、トランザクションはロールバックすることはできません。

結論2:例外が@Transactionalことができるだけかどうかをキャッチしてみてください **影響を受けることが認識されます。エラーは、それが役割を担うことができるポイントに知覚できる側面がスローされた場合。**

トランザクションのネスト影響

最初の実験後、結論はまだ保持し、両方の内部、rollbackFor = Exception.class時間と組み合わせるとのRuntimeException報告し、ロールバックされない場合には、である;両方の内部および非のRuntimeExceptionエラーを報告し、ロールバックされません。我々はrollbackFor = Exception.class追加する場合は、両方の方法を内部でエラーがロールバックされます。コードが与えられていません。次に、以下の2つのケースをテストします。

    @GetMapping("/out")
    @Transactional( rollbackFor = Exception.class)
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
        throw new Exception();
    }
    @Transactional
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
//        throw new Exception();
    }

内側と外側の両方のトランザクションを、それぞれの試験状況を与えられたことなく、トランザクションプラスrollbackFor = Exception.class、外側(符号量を簡単にするために、コードが出与えられてのみ与えられる)場合は、ロールバックすることができます。ので、どのような場合には、エラーはそのトランザクション処理から放り出され、その外の非のRuntimeExceptionエラーを処理する能力と、rollbackFor = Exception.classを追加し、それは、トランザクションが通常の状態にロールバックされる可能性があります。

外なし、外側は与えられている、のは2、トランザクションプラスrollbackFor = Exception.classの内側の場合を見てみましょう。

    @GetMapping("/out")
    @Transactional
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
        throw new Exception();
    }
    
    @Transactional( rollbackFor = Exception.class)
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
    }

トランザクションは、我々はなど、心配これについて話をしない、それが外にロールバック一緒に失敗した理由を明らかに、ああ、強力なトランザクション処理能力を持っている疑問を持っている、ロールバックすることはできません。

その後、再び内部を与えられました:

    @GetMapping("/out")
    @Transactional
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
    }
     @Transactional( rollbackFor = Exception.class)
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
        throw new Exception();
    }

ねえ、この時間は、通常、ロールバックされています。私の神、無処理能力外のこの時間は、なぜ捨て、また、ロールバックされた内部エラーを受け入れます!内側と外側の業務は右常に生きて死ぬかのように表示されますか?元は、トランザクション@パラメータ、ソースを見て、メモやデフォルト値があります:

Propagation propagation() default Propagation.REQUIRED;

トランザクションが存在することがわかっている場合、トランザクションを入れ子に、トランザクションに参加したとき、平均必須ではなく、新しいトランザクションを作成し、どの2つのトランザクションが単に存在しない、唯一の一つとなっています!このパラメータの他の値については、この記事では、試験されるべきではありません。私たちの前の質問、アウト与えられたときに、この時間は、トランザクションを見ることに戻ると、そこ以外のRuntimeExceptionを処理する能力がありませんので、コードが完成し、「二つのトランザクション」のように見える、ロールバックに失敗したことは増加rollbackFor = Exception.class引数はありません。エラーがある場合は、トランザクションは、非のRuntimeExceptionの処理能力に追加されているので、ロールバックを完了するためのコードは成功です。

結論3:原因REQUIREDプロパティは、「二つのトランザクションは、」実際のトランザクション、非のRuntimeExceptionを処理する能力を追加するかどうか、エラーの処理時間を表示する機能です。

キャッチとトランザクション巣の複合効果を試してみてください

一般的なインパクトの問題を探求するように設定一二〇から三の終了時に、あまりにも多くの場合ので、あまりにも多くのコードを示してはいけない、はるかに簡単です。

結論

結論1:@Transactionalの場合は、あなたがそれ以外のRuntimeExceptionエラーロールバックを確認したい場合は、あなたがrollbackFor = Exception.classパラメータを追加する必要があり、のRuntimeExceptionエラーロールバックを保証することができます。
結論2:例外が@Transactionalことができるだけかどうかをキャッチしてみてください **影響を受けることが認識されます。エラーは、それが役割を担うことができるポイントに知覚できる側面がスローされた場合。
結論3:原因REQUIREDプロパティは、「二つのトランザクションは、」実際のトランザクション、非のRuntimeExceptionを処理する能力を追加するかどうか、エラーの処理時間を表示する機能です。**

おすすめ

転載: www.cnblogs.com/pjjlt/p/10926398.html