Force Spring/JPA/Hibernate/JDBC zu wiederholen einer fehlgeschlagenen beginTransaction?
Manchmal eine db-Transaktion kann nicht beginnen, weil der eine einfache SocketException beim erreichen MySQL. In der aktuellen codebase, alle SQL-oder JPQL-code befindet sich in Klassen mit der @Transactional annotation (org.springframework.die Transaktion.annotation). Eine Transaktion wird erstellt, für mich, für jede Methode aufrufen, um eine annotierte Klasse. Dies macht es schwierig, code zu schreiben, der wiederverwendet werden kann über alle db-Aufrufe.
Eine Lösung wäre die db-code innerhalb einer Loop-Schleife: Es wird wiederholt die Transaktion ein paar mal. Das funktioniert, aber ich würde es vorziehen, nicht zu streuen mein code voll-Schleifen (eine für jede db-call).
Gibt es einen Weg, um entweder eine der folgenden frameworks wiederholen einer fehlgeschlagenen beginTransaction automatisch?: Spring, JPA, Hibernate, c3p0, MySQL-JDBC-Treiber
Referenz, hier ist ein Stück der log:
java.net.SocketException
MESSAGE: Connection reset
STACKTRACE:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1910)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3170)
at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5273)
at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:91)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1353)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:38)
at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:70)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:52)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:330)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:374)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
PS. Ich hasse automagic-frameworks, die angeblich alle Probleme lösen. Es war nicht meine Entscheidung, in dieses Projekt.
- Sie sagen, der code ist an sich bereits zu viele Geschäfte und zu wiederholen, wird mehr erstellen. Wie es scheint, die Zeit zu beheben, wie die app funktioniert-Transaktionen.
- Ich weiß nicht, was Sie für eine datasource, aber Sie könnten in der Lage sein, dieses problem zu lösen mit der Konfiguration herum, wie die verbindungen sind ausgeliehen. Zum Beispiel, apache commons BasicDataSource hat testOnBorrow, validationQuery und removeAbandoned zu helfen, stellen Sie sicher, dass Sie eine gültige Verbindung zu beginnen. commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/...
- Wenn ich die chance bekomme, um die redo-Transaktion behandeln, werde ich fallen Frühling insgesamt und gehen Sie direkt zu JPA (oder noch besser: JDBC).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht wollen, zu bringen retry-loops in deinem code, vielleicht können Sie verwenden, AOP implementieren retry-Funktionalität. Es ist ein Beispiel, eine solche Beratung in der Spring-Dokumentation.
order
von der Beratung geschehen, bevor oder nachdem die vorhandene Transaktion beraten (je nachdem, ob Sie es erneut versuchen möchten, die innerhalb einer vorhandenen Transaktion, oder eine neue zu beginnen jedes mal, wenn Sie wiederholen).Erstellen Sie eine utility-Methode mit einem TransactionCallback als parameter. In dieser Methode sollten die looping-und exception-handling, mit einem TransactionTemplate.
Wenn Sie brauchen, um eine Abfrage ausführen, mit Wiederholungen, die diese Methode verwenden.
Sehen die Frühjahr Referenz für details.
Beispielsweise Ihre Berufung code würde wie folgt Aussehen: