Pokazywanie transakcji Spring w dzienniku


102

Sprężynę skonfigurowałem ze wsparciem transakcyjnym. Czy istnieje sposób na rejestrowanie transakcji, aby upewnić się, że wszystko skonfigurowałem poprawnie? Wyświetlanie w dzienniku to dobry sposób, aby zobaczyć, co się dzieje.

Odpowiedzi:


96

w swoim log4j.properties(alternatywne rejestratory lub format xml log4j, sprawdź dokumentację)

W zależności od menedżera transakcji możesz ustawić poziom rejestrowania struktury Spring, aby uzyskać więcej informacji o transakcjach. Na przykład, w przypadku używania JpaTransactionManager, ustawiasz

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

(to jest pakiet twojego menedżera transakcji), a także

log4j.logger.org.springframework.transaction=INFO

Jeśli INFOto nie wystarczy, użyjDEBUG


7
INFOpoziom w ogóle nie pokaże żadnej aktywności tx, byłoby to zbyt szczegółowe. DEBUGbędzie tam potrzebny.
— skaffman

@Bozho Mam JpaTransactionManager i chcę monitorować, kiedy połączenie jest pożyczane z puli i kiedy zostało zwolnione dla określonej transakcji.
— Ali

wtedy trzeba by zmienić konfigurację logowania dla puli połączeń
— Bozho

co jeśli użyjemy mybatis + slf4j + logback + springboot?
— lily

66

Dla mnie dobrą konfiguracją logowania do dodania była:

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

Pokaże mi taki dziennik:

2012-08-22 18: 50: 00,031 TRACE - Pobieranie transakcji dla [com.MyClass.myMethod]

[moje własne instrukcje dziennika z metody com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Zakończenie transakcji dla [com.MyClass.myMethod]


1
Wspaniały! Nie ma potrzeby posiadania wszystkich informacji / debugowania / rejestrowania śledzenia innych pakietów, gdy tego właśnie szukasz: D
— Johanneke

31

Dla aplikacji Spring Boot z application.properties

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

lub jeśli wolisz Yaml ( application.yaml)

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

1
Działa jak urok
— Ben

9

Najciekawsze informacje dziennika JtaTransactionManager.java(jeśli to pytanie nadal dotyczy JtaTransactionManager) są rejestrowane w DEBUGpierwszej kolejności. Zakładając, że masz log4j.propertiesgdzieś na ścieżce klas, sugerowałbym użycie:

log4j.logger.org.springframework.transaction=DEBUG

7

Ponieważ możesz uzyskać dostęp do klas Spring w czasie wykonywania, możesz określić status transakcji. Ten artykuł może Ci pomóc:

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


Bardzo zepsuty, ale spróbuj: Wskazówki dotyczące debugowania adnotacji @Transactional Springa (jeszcze nie wypróbowałem). Używa TransactionSynchronizationManager, aby uzyskać status transakcji. Kod powinien prawdopodobnie wykorzystywać zmienną lokalną wątku do buforowania odwołania do isActualTransactionActive()zamiast pobierania go przy każdym wywołaniu logowania.
— David Tonhofer

6

Możesz również włączyć rejestrowanie JDBC:

log4j.logger.org.springframework.jdbc=DEBUG

1

Oto kod, którego używam w mojej implementacji Logback Layout, pochodzący z ch.qos.logback.core.LayoutBase .

Tworzę zmienną lokalną wątku do przechowywania odniesienia do metody org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Za każdym razem, gdy drukowany jest nowy wiersz dziennika, getSpringTransactionInfo()jest wywoływany i zwraca jednoznakowy ciąg, który trafia do dziennika.

Bibliografia:

Kod:

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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.