Mischen von programmatischen und deklarativen Transaktionen in Legacy-Software

8

Meine Frage betrifft mögliche Nebenläufigkeitsprobleme beim Mischen von programmatischen und deklarativen Transaktionen. Ich entwickle eine Legacy-Software (Spring + Hibernate), die Datenbankverbindungen und Transaktionen programmatisch abwickelt.

%Vor%

Die Software verfügt über neuere Module, die Spring-Datenarchitektur mit deklarativen Transaktionen (@Transactional) verwenden. Wir haben in seltenen Fällen Datenbank-Deadlocks mit Microsoft SQL Server festgestellt, wenn neuere Spring-Services von innerhalb von "manuell" geöffneten Transaktionen aufgerufen werden. Ich denke, das Problem ist, dass es zwei verschachtelte Transaktionen gibt, die dieselben Tabellen lesen / schreiben, die Deadlocks verursachen.

%Vor%

Gibt es eine Möglichkeit, diese Transaktionen sicher zu mischen oder die bereits gestartete Transaktion in beiden zu verwenden? Soll ich die manuell / programmgesteuert geöffnete Transaktion vor dem Aufruf von Spring @ Service / @ Repository-Methoden einfach schließen? Sowohl Spring als auch HibernateUtil verwenden denselben Entity Manager für Datenbankverbindungen.

    
anssias 11.02.2016, 14:07
quelle

1 Antwort

6

Wenn es um das Verhalten der Transaktionen geht, gibt es keinen Unterschied zwischen deklarativen und programmatischen / manuellen. Mit deklarativen Transaktionen können Sie Transaktionsgrenzen präziser und lesbarer abgrenzen, das ist alles. Unter der Haube wird Spring das gleiche tun, was Sie manuell tun würden, um Transaktionen zu starten und zu committen / zurückzusetzen.

  

Ich denke, das Problem ist, dass es zwei verschachtelte Transaktionen gibt   Lesen / Schreiben derselben Tabellen, die Deadlocks verursachen.

Sehr möglich.

  

Gibt es eine Möglichkeit, diese Transaktionen sicher zu kombinieren oder bereits zu nutzen?   Transaktion in beiden gestartet?

Ob es in Ihrem spezifischen Teilecode sicher ist, hängt stark davon ab, was der Code tut. Wenn eine geschachtelte Transaktion Deadlock verursacht, ist sie offensichtlich nicht sicher und hat nichts damit zu tun, wie Sie die verschachtelte Transaktion erhalten haben (manuell oder Spring hat sie gestartet, als sie eine mit @Transactional(propagation = Propagation.PROPAGATION_REQUIRES_NEW) annotierte Methode abfing).

  

Sollte ich nur die manuell / programmatisch geöffnete Transaktion schließen?   vor dem Aufruf von Spring @Service / @Repository Methoden?

Auch hier kommt es darauf an, was Sie lösen müssen. Wenn Sie möchten, dass die äußere Transaktion fortgesetzt wird, nachdem die verschachtelte Transaktion abgeschlossen wurde, sollten Sie dies nicht tun. Sonst kannst du.

TransactionTemplate ist der empfohlene Weg um Transaktionen manuell mit Spring zu starten, da Spring dann Transaktionsbegrenzungen kennt, was bedeutet, dass eine solche Transaktion genauso behandelt wird, als wenn sie deklarativ mit einer Spring-Annotation gestartet würde.

    
Dragan Bozanovic 11.02.2016, 16:50
quelle

Tags und Links