Springトランザクションロールバック
1. 発生した問題
1つのメソッドで複数のデータベース保存操作を行うと、中間のデータベース操作でエラーが発生します。疑似コードは次のとおりです:
public method() { Dao1.save(Person1); Dao1.save(Person2); Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中 Dao1.save(Person2); }
予想される状況: エラーが発生する前のすべてのデータベース保存操作はロールバックされ、保存されません
通常の状況: 前のデータベース操作が実行され、すべてのデータベース操作エラーが開始されますエラー発生以降はデータ保存に失敗します。これは私たちが望む結果ではないはずです。
この状況に遭遇した場合、Spring トランザクションを使用してこの問題を解決できます。
2. 例外の基本知識
1) 例外アーキテクチャ
例外の継承構造: Throwable は基本クラスであり、Error と Exception は Throwable を継承し、RuntimeException と IOException は Exception を継承します。 Error および RuntimeException とそのサブクラスは非チェック例外 (未チェック) になり、その他の例外はチェック例外 (チェックあり) になります。
2) エラー例外
エラーは、プログラムの実行中に非常に深刻で回復不可能なエラーが発生したことを示します。この場合、アプリケーションは、JAVA 仮想マシンのエラーなど、操作を終了することしかできません。 Error はチェックされていない例外であり、コンパイラは Error が処理されたかどうかをチェックしないため、プログラム内で Error タイプの例外をキャッチする必要はありません。通常の状況では、プログラム内で Error タイプの例外がスローされるべきではありません。
3) RuntimeException
Exception には、RuntimeException およびその他の非 RuntimeException 例外が含まれます。
RuntimeException は Unchecked Exception であり、プログラムが RuntimeException を処理するかどうかをコンパイラがチェックしないことを意味します。プログラム内で RuntimException 型の例外をキャッチする必要はなく、メソッド本体で RuntimeException クラスを宣言する必要もありません。 。 RuntimeException が発生した場合は、プログラム内でプログラミング エラーが発生したことを意味するため、RuntimeException をキャッチするのではなく、エラーを見つけてプログラムを変更する必要があります。
4) チェック済み例外
チェック済み例外。これはプログラミングで最もよく使用される例外でもあり、Exception から継承され、RuntimeException ではないすべての例外がチェック済み例外、IOException、および ClassNotFoundException です。 JAVA 言語では、チェックされた例外を処理する必要があると規定されており、コンパイラはこれをチェックし、メソッド本体でチェックされた例外を宣言するか、catch ステートメントを使用してチェックされた例外を処理用にキャプチャします。それ以外の場合は、コンパイルできません。
3. 例
ここで使用されるトランザクション構成は次のとおりです:
<!-- Jpa 事务配置 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
Spring 構成ファイルで、データ ソースのdefaultAutoCommit が True に設定されている場合、メソッドが例外をキャッチすると、トランザクションはたとえば、設定ファイルにそのようなレコードがある場合、このパラメータが設定されていないことがわかります。自動的に送信されますか? 答えは「いいえ」です。データベース接続プールとして com.alibaba.druid.pool.DruidDataSource を使用します。以下にソース コードを示します
。
状況 1: 例外がプログラムで手動でキャッチされない場合<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="xxx" value="xxx"/> <property name="xxx" value="xxx"/> .... <property name="defaultAutoCommit" value="true" /> </bean>状況 2: 例外がプログラムでキャッチされた場合
@Transactional(rollbackOn = { Exception.class }) public void test() throws Exception { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 会回滚。 }
トランザクションを手動でロールバックするには、次のように記述するだけです:
@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。 } catch (Exception e) { e.printStackTrace(); } }
読んでいただきありがとうございます!ありがとう!