Einige Fragen zum Grails-Service

8

Ich arbeite mit einer Grails-Webanwendung und bekomme so viele seltsame Dinge, wenn ich den Grails-Dienst verwende. Daher möchte ich einige Fragen dazu stellen, damit ich mehr über die Grails-Dienste erfahren kann. Dies wird sehr hilfreich für mich sein (und vielleicht auch für andere). Danke im Voraus.

  1. Wenn ein Dienst mit statischem transactional = true konfiguriert ist, werden alle Datenänderungen in DB gelöscht, nachdem eine Methode mit einem Objekt aufgerufen wurde, das schmutzig ist und in der Hibernate-Sitzung gesperrt ist?

  2. Kann ich @Transactional Annotation auf Klassenebene anstelle von static transactional = true verwenden? Und ist es möglich, @Transactional(readOnly = true) bei einigen Methoden zu setzen, die ich nur will, dass sie Daten von DB lesen (abfragen, finden)?

  3. Wie steht es mit der Transaktionsvererbung? Ich meine, wenn der übergeordnete Dienst static transactional = true konfiguriert ist und der untergeordnete Dienst seine eigene @Transactional -Anmerkung (für die Klasse) und einige @Transactional(readOnly = true) (für einige Methoden) hat, was passiert, wenn ich eine Methode bei der übergeordneten Methode aufruft vom Kind eins?

  4. Funktioniert die Transaktion mit einem abstrakten Service? Wie ich weiß, können wir mit dem abstrakten Service seine Bean nicht initialisieren, und vielleicht gibt es beim Starten der App einige Unterschiede im Grails-Kontext.

Đinh Hồng Châu 02.12.2011, 03:41
quelle

1 Antwort

7

Sie sollten eine Frage pro Frage stellen:)

Für Frage 1, ja - die Spring / Hibernate-Integration stellt sicher, dass vor dem Commit ein Flush stattfindet. So werden die Aufrufe von save() und delete() gelöscht und es ist nicht nötig, flush: true hinzuzufügen. Außerdem werden schmutzige Instanzen, für die Sie save() nicht aufgerufen haben, ebenfalls geleert, es sei denn, Sie rufen discard() auf.

Für # 2: Dienste sind standardmäßig transaktional, also ist transactional = true tatsächlich redundant - Sie müssen es nur angeben, um transactional = false zu sagen. Der automatische Transaktions-Wrapper, der erstellt wird, wird jedoch nur ausgeführt, wenn keine @Transactional -Anmerkungen vorhanden sind. Wenn Sie eine oder mehrere Anmerkungen haben, definieren diese eine Transaktionsabgrenzung. Also standardmäßig (d. H. Keine Anmerkungen und entweder keine transactional Eigenschaft oder transactional = true ) sind alle Methoden transaktional, aber wenn Sie nur eine Teilmenge der Methoden kommentieren, werden nur diese transaktional sein.

Normalerweise würden Sie Annotationen verwenden, wenn Sie nicht standardmäßiges Verhalten wünschen, d. h. benutzerdefinierte Propagierung, Isolation, Timeout usw. (oder wie in Ihrem Beispiel schreibgeschützt).

Sie können Annotationen auf Klassenebene durchführen, um für alle Methoden die gleiche Konfiguration zu erhalten, und optional einzelne Methoden annotieren, um die Standardeinstellungen für den Klassenbereich zu überschreiben.

Für # 3 und # 4 gelten die Standardregeln (siehe # 2). Wenn die Unterklasse Annotationen hat, wird transactional = true von dieser Klasse oder einer Elternklasse ignoriert, da Sie Grails mithilfe von Anmerkungen gesagt haben, dass Sie die Dinge selbst konfigurieren.

Da abstrakte Dienste nicht instanziiert werden können, wird die konkrete Unterklasse, die tatsächlich instanziiert ist, ein kombiniertes Verhalten von der Basisklasse und von sich selbst haben. Wenn alles transactional = true ist, dann ist es einfach, und wenn Sie irgendwelche Anmerkungen haben, dann definieren sie die Regeln.

Das Aufrufen von Methoden in der Oberklasse würde sich genauso verhalten wie das Aufrufen von Methoden in der aktuellen Klasse. Aber das Verhalten ist ein wenig kontraintuitiv, wenn Sie die Auswirkungen des Proxy-Ansatzes von Spring nicht berücksichtigt haben. Wenn Sie eine Transaktionsmethode aufrufen, fängt der Proxy den Aufruf ab und verknüpft die aktive Transaktion oder startet bei Bedarf eine neue Transaktion oder startet eine neue, wenn REQUIRES_NEW angegeben wird. Aber sobald Sie in der richtigen Klasse sind und eine andere Methode aufrufen, umgehen Sie den Proxy. Wenn Sie also eine andere Methode mit anderen Anmerkungseinstellungen aufrufen, werden sie ignoriert. Wenn Sie das tun, finden Sie in dieser Mailing-Liste Diskussion für was ist los und wie man damit arbeitet: Ссылка

    
Burt Beckwith 02.12.2011, 04:20
quelle