Anzeigen einer Spring-Transaktion im Protokoll


102

Ich habe die Feder mit Transaktionsunterstützung konfiguriert. Gibt es eine Möglichkeit, Transaktionen zu protokollieren, um sicherzustellen, dass ich alles richtig eingerichtet habe? Das Anzeigen im Protokoll ist eine gute Möglichkeit, um zu sehen, was passiert.

Antworten:


95

in Ihrem log4j.properties(für alternative Logger oder das XML-Format von log4j überprüfen Sie die Dokumente)

Abhängig von Ihrem Transaktionsmanager können Sie die Protokollierungsstufe des Spring Frameworks so einstellen, dass Sie weitere Informationen zu Transaktionen erhalten. Zum Beispiel, wenn Sie verwenden JpaTransactionManager, setzen Sie

log4j.logger.org.springframework.orm.jpa=INFO

(Dies ist das Paket Ihres Transaktionsmanagers) und auch

log4j.logger.org.springframework.transaction=INFO

Wenn INFOnicht genug, verwenden SieDEBUG


7
INFOlevel zeigt überhaupt keine tx-Aktivität an, es wäre zu ausführlich. DEBUGwird dort notwendig sein.
Skaffman

@Bozho Ich habe JpaTransactionManager und möchte überwachen, wann eine Verbindung aus dem Pool ausgeliehen wurde und wann sie für eine bestimmte Transaktion freigegeben wurde.
Ali

dann müssten Sie die Protokollierungskonfiguration für Ihren Verbindungspool ändern
Bozho

Was ist, wenn wir mybatis + slf4j + logback + springboot verwenden?
Lilie

66

Für mich war eine gute Protokollierungskonfiguration zum Hinzufügen:

log4j.logger.org.springframework.transaction.interceptor = trace

Es wird mir folgendes Protokoll zeigen:

2012-08-22 18: 50: 00,031 TRACE - Transaktion für [com.MyClass.myMethod] abrufen

[meine eigenen Protokollanweisungen von der Methode com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Abschluss der Transaktion für [com.MyClass.myMethod]


1
Toll! Sie müssen nicht alle Informationen / Debug / Trace-Protokolle anderer Pakete haben, wenn Sie danach suchen: D
Johanneke

31

Für Spring Boot-Anwendung mit application.properties

logging.level.ROOT=INFO
logging.level.org.springframework.orm.jpa=DEBUG
logging.level.org.springframework.transaction=DEBUG

oder wenn Sie Yaml bevorzugen ( application.yaml)

logging:
   level:
      org.springframework.orm.jpa: DEBUG
      org.springframework.transaction: DEBUG

1
Funktioniert wie ein Zauber
Ben

9

Die interessantesten Protokollinformationen von JtaTransactionManager.java(wenn es sich bei dieser Frage noch um das handelt JtaTransactionManager) werden DEBUGvorrangig protokolliert . Angenommen, Sie haben log4j.propertiesirgendwo auf dem Klassenpfad, würde ich daher empfehlen, Folgendes zu verwenden:

log4j.logger.org.springframework.transaction=DEBUG

7

Da Sie zur Laufzeit auf Spring-Klassen zugreifen können, können Sie den Transaktionsstatus bestimmen. Dieser Artikel kann Ihnen helfen:

https://dzone.com/articles/monitoring-declarative-transac


Sehr kaputt, aber versuchen Sie es: Tipps zum Debuggen der @Transactional Annotation von Spring (habe es selbst noch nicht ausprobiert). Es verwendet TransactionSynchronizationManager , um den Transaktionsstatus abzurufen. Der Code sollte wahrscheinlich eine threadlokale Variable verwenden, um den Verweis auf das zwischenzuspeichern, isActualTransactionActive()anstatt ihn bei jedem Protokollierungsaufruf abzurufen.
David Tonhofer

6

Sie können auch die JDBC-Protokollierung aktivieren:

log4j.logger.org.springframework.jdbc=DEBUG

1

Hier ist ein Code, den ich in meiner Logback-Layout-Implementierung verwende, die von ch.qos.logback.core.LayoutBase abgeleitet ist .

Ich erstelle eine threadlokale Variable, um den Verweis auf die Methode zu speichern org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Immer wenn eine neue Protokollzeile ausgedruckt wird, getSpringTransactionInfo()wird sie aufgerufen und es wird eine einstellige Zeichenfolge zurückgegeben, die in das Protokoll aufgenommen wird.

Verweise:

Code:

private static ThreadLocal<Method> txCheckMethod;

private static String getSpringTransactionInfo() {
    if (txCheckMethod == null) {
        txCheckMethod = new ThreadLocal<Method>() {
            @Override public Method initialValue() {           
                try {
                    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
                    Class<?> tsmClass = contextClassLoader.loadClass("org.springframework.transaction.support.TransactionSynchronizationManager");
                    return tsmClass.getMethod("isActualTransactionActive", (Class<?>[])null);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }                      
            }
         };    
    }
    assert txCheckMethod != null;
    Method m = txCheckMethod.get();
    String res;
    if (m == null) {
        res = " "; // there is no Spring here
    }
    else {
        Boolean isActive = null;
        try {
            isActive = (Boolean) m.invoke((Object)null);
            if (isActive) {
                res = "T"; // transaction active                    
            }
            else {
                res = "~"; // transaction inactive
            }
        }
        catch (Exception exe) {
            // suppress 
            res = "?";
        }
    }
    return res;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.