Im Gegensatz zu Java, Sie müssen nicht die (überprüft) Ausnahmen erklären, die von einer starken Methode geworfen werden, da alle nicht angemeldete geprüfte Ausnahmen in einem UndeclaredThrowableException gewickelt werden.
Sie scheinen zu implizieren, dass Groovy Wraps Ausnahmen von einem UndeclaredThrowableException geprüft, dann ist dies nicht der Fall. Wenn ein Grails-Dienst eine ungeprüfte Exception wirft die Exception schließlich von einer UndeclaredThrowableException wrappped aber dies ist ein java.lang.reflection Mechanismus und tritt nur dann auf, wenn eine Proxy-Klasse beteiligt ist.
Dies geschieht, der Fall zu sein, weil ein Grails Dienst beteiligt ist. Ich bin mir nicht sicher, wie viele Proxy-Klassen genau beteiligt sind, durch mindestens eine ist: eine Klasse, die die Transaktion tut Handling (von Spring).
Die Klasse wird jede Methode im Service mit einer Transaktion umbrechen und die Transaktion rückgängig machen, wenn eine RuntimeException auftritt. Die Verarbeitung von Spring-Transaktionen wird standardmäßig nicht rückgängig gemacht, wenn eine Ausnahme aktiviert ist.
Java
Dies macht Sinn, in plain old Java, da der Entwickler die Ausnahme in dem Anwendungscode sehen und wird gewarnt, etwas dagegen zu tun. Wenn der Entwickler schlau ist, wird er im Rahmen einer Transaktion mit Ausnahmen umgehen.Wenn er die Transaktion nicht zurücksetzt, sagt er im Wesentlichen: "In dieser Situation ist die Datenintegrität, die durch die Transaktion bereitgestellt wird, für mich nicht wichtig. Ich werde auf andere Weise“
Groovy
diese Fehler beheben Dies macht keinen Sinn in einer Groovy Welt machen, weil die Groovy-Compiler nicht den Umgang mit Ausnahmen nicht erzwingen. Es behandelt Ausnahmen genauso wie RuntimeExceptions.
Es gibt jedoch eine Einschränkung: Der Reflektionsmechanismus sieht eine Exception, die vom Proxy ausgelöst wird und nicht in der Methodensignatur des ursprünglichen Service enthalten ist. Dies ist möglich, weil:
- Groovy erzwingt nicht die Ausnahmen Umgang
- Ein Proxy-Methode immer alle Throwable (check InvocationHandler JavaDoc) werfen
Da die verwendete Reflexionsmechanismus von Java ist, Es muss den Java-Regeln entsprechen. Es muss also die Exception in eine RuntimeException umbrechen, in diesem Fall eine UndeclaredThrowableException.
Grails
Jetzt wird es wirklich schwierig, denn wenn Sie Ihre Service-Methode von einem Controller-Aufruf und eine Ausnahme auftritt. Sie werden eine RuntimeException-Blase sehen (wegen eines versteckten Mechanismus), aber Ihre Transaktion wird nicht zurückgesetzt (wegen eines versteckten Mechanismus).
Dieses Verhalten ist sehr gefährlich wie der Entwickler wirklich zu erinnern, hat richtig mit allen möglichen Ausnahmen zu behandeln (das der Compiler mit nicht helfen) oder dem Entwickler muss sicherstellen, dass jeder Dienst ordnungsgemäß mit @Transactional angewiesen wird (rollbackFor = Throwable).
Dies ist ein Design-Problem, das die Entwickler von Grails meiner Meinung nach übersehen haben, als sie es zum ersten Mal entwarfen. Aber ich denke, das Standardverhalten ist so falsch und so gefährlich, das sollte wirklich geändert werden.
Nun, ich brauche überprüfte Ausnahmen in meinem Fall, weil es mehrere gibt, die ich von der Stripe API behandeln muss. Ich habe einen anderen Weg eingeschlagen, da ich auch immer eine RuntimeException auslösen muss, damit meine Transaktionen korrekt zurückgesetzt werden. Ich markiere deine Antwort als richtig, weil es die richtige Antwort auf meine Frage ist. Vielen Dank. – Gregg
Gern geschehen. Übrigens, Sie können Transaktionen für alle Ausnahmen rückgängig machen (aktiviert und deaktiviert), indem Sie den Grails-Diensten die folgende Anmerkung hinzufügen: @Transactional (rollbackFor = Throwable) –
Danke für den Tipp! Wusste ich nicht. – Gregg