Spring-Transaktions-Rollback
1. Aufgetretene Probleme
Wenn wir mehrere Datenbankspeichervorgänge in einer Methode durchführen, tritt ein Fehler im Zwischenvorgang der Datenbank auf. Der Pseudocode lautet wie folgt:
public method() { Dao1.save(Person1); Dao1.save(Person2); Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中 Dao1.save(Person2); }
Erwartete Situation: Alle Datenbankspeichervorgänge vor dem Auftreten des Fehlers werden zurückgesetzt, d. h. nicht gespeichert.
Normale Situation: Der vorherige Datenbankvorgang wird ausgeführt ausgeführt werden, und alle Datenspeichervorgänge, die bei und nach einem Datenbankbetriebsfehler beginnen, schlagen fehl. Das sollte nicht das Ergebnis sein, das wir wollen.
In dieser Situation können wir Spring-Transaktionen verwenden, um dieses Problem zu lösen.
2. Einige Grundkenntnisse über Ausnahmen
1) Ausnahmearchitektur
Ausnahmevererbungsstruktur: Throwable ist die Basisklasse, Error und Exception erben Throwable, RuntimeException und IOException usw . Erbt Ausnahme. Error und RuntimeException sowie ihre Unterklassen werden zu ungeprüften Ausnahmen (ungeprüft), und andere Ausnahmen werden zu geprüften Ausnahmen (geprüft).
2) Fehlerausnahme
Fehler weist darauf hin, dass während der Ausführung des Programms ein sehr schwerwiegender und nicht behebbarer Fehler aufgetreten ist Brechen Sie den Vorgang ab, wenn beispielsweise in der JAVA Virtual Machine ein Fehler auftritt. Fehler ist eine ungeprüfte Ausnahme. Der Compiler prüft nicht, ob der Fehler behandelt wurde, und es besteht keine Notwendigkeit, Ausnahmen vom Typ Fehler im Programm abzufangen. Unter normalen Umständen sollten in Programmen keine Ausnahmen vom Typ Fehler ausgelöst werden.
3) RuntimeException
Ausnahme umfasst RuntimeException und andere Nicht-RuntimeException-Ausnahmen.
RuntimeException ist eine ungeprüfte Ausnahme, was bedeutet, dass der Compiler nicht prüft, ob das Programm RuntimeException verarbeitet. Es besteht keine Notwendigkeit, Ausnahmen vom Typ RuntimException im Programm abzufangen, und es besteht keine Notwendigkeit, die RuntimeException-Klasse in zu deklarieren Methodenkörper. Wenn eine RuntimeException auftritt, bedeutet dies, dass im Programm ein Programmierfehler aufgetreten ist. Daher sollte der Fehler gefunden und das Programm geändert werden, anstatt die RuntimeException abzufangen.
4) Geprüfte Ausnahme
Geprüfte Ausnahme, die auch die am häufigsten verwendete Ausnahme in der Programmierung ist. Alle Ausnahmen, die von Exception erben und keine RuntimeException sind, sind geprüfte Ausnahmen im Bild oben und ClassNotFoundException. Die JAVA-Sprache schreibt vor, dass die geprüfte Ausnahme verarbeitet werden muss und entweder eine geprüfte Ausnahme im Methodenkörper deklariert oder eine Catch-Anweisung verwendet, um die geprüfte Ausnahme zur Verarbeitung zu erfassen.
3. Beispiel
Die hier verwendete Transaktionskonfiguration lautet wie folgt:
<!-- 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" />
In der Spring-Konfigurationsdatei, wenn die Standardeinstellung „AutoCommit“ lautet Die Datenquelle ist: Wenn sie „True“ ist, wird die Transaktion nicht zurückgesetzt, wenn die Methode die Ausnahme selbst abfängt. Wenn die Ausnahme nicht selbst abgefangen wird, wird die Transaktion zurückgesetzt, wie im folgenden Beispiel
Beispielsweise gibt es einen solchen Eintrag in der Konfigurationsdatei
<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>
Vielleicht stellen Sie fest, dass Sie diesen Parameter nicht konfiguriert haben. Wird er nicht automatisch übermittelt? , ich verwende hier com.alibaba.druid.pool.DruidDataSource Als Datenbankverbindungspool ist der Standardwert defaultAutoCommit wahr. Sie können den Quellcode unten sehen
Dann dort Es gibt jetzt zwei Situationen
Situation 1: Wenn es nicht manuell im Programm erfasst wird Ausnahme
@Transactional(rollbackOn = { Exception.class }) public void test() throws Exception { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 会回滚。 }
Situation 2: Wenn wir die Ausnahme selbst im Programm abfangen
@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。 } catch (Exception e) { e.printStackTrace(); } }
Wenn wir nun die Ausnahme manuell abfangen müssen und sie auch auslösen möchten, was soll ich tun, wenn die Zeit zurückgesetzt werden kann?
Schreiben Sie es einfach so, um die Transaktion manuell rückgängig zu machen:
@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2(); } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常, //doDbStuff1()是会回滚的 } }
Vielen Dank fürs Lesen! Danke!
Weitere Artikel zum Java Spring-Transaktions-Rollback finden Sie auf der chinesischen PHP-Website!