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.

cometta
źródło

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

Bozho
źródło
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]

Sander S.
źródło
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
Mariusz S.
źródło
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
Pascal Thivent
źródło
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

Michel Gokan
źródło
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
Energia
źródło
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;
}
David Tonhofer
źródło