Affichage d'une transaction Spring dans le journal

102

J'ai configuré Spring avec un support transactionnel. Existe-t-il un moyen de consigner les transactions simplement pour m'assurer que j'ai tout configuré correctement? L'affichage dans le journal est un bon moyen de voir ce qui se passe.

cometta
la source

Réponses:

96

dans votre log4j.properties(pour les enregistreurs alternatifs, ou le format xml de log4j, consultez la documentation)

En fonction de votre gestionnaire de transactions, vous pouvez définir le niveau de journalisation du framework Spring afin qu'il vous donne plus d'informations sur les transactions. Par exemple, en cas d'utilisation JpaTransactionManager, vous définissez

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

(c'est le package de votre gestionnaire de transactions), et aussi

log4j.logger.org.springframework.transaction=INFO

Si cela INFOne suffit pas, utilisezDEBUG

Bozho
la source
7
INFOlevel ne montrera aucune activité tx du tout, ce serait trop détaillé. DEBUGsera nécessaire là-bas.
skaffman
@Bozho J'ai JpaTransactionManager et je veux surveiller quand une connexion est empruntée au pool et quand elle a été libérée pour une transaction spécifique.
Ali le
alors vous devrez changer la configuration de journalisation pour votre pool de connexion
Bozho
et si nous utilisons mybatis + slf4j + logback + springboot?
Lily
66

Pour moi, une bonne configuration de journalisation à ajouter était:

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

Cela me montrera un journal comme ça:

2012-08-22 18: 50: 00,031 TRACE - Obtention de la transaction pour [com.MyClass.myMethod]

[mes propres instructions de journal de la méthode com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Fin de la transaction pour [com.MyClass.myMethod]

Sander S.
la source
1
Génial! Pas besoin d'avoir toutes les informations / débogage / trace des autres paquets, quand c'est ce que vous cherchez: D
Johanneke
31

Pour l'application Spring Boot avec application.properties

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

ou si vous préférez Yaml ( application.yaml)

logging:
   level:
      org.springframework.orm.jpa: DEBUG
      org.springframework.transaction: DEBUG
MariuszS
la source
1
Fonctionne comme un charme
Ben
9

Les informations de journal les plus intéressantes de JtaTransactionManager.java(si cette question concerne toujours le JtaTransactionManager) sont enregistrées en DEBUGpriorité. En supposant que vous ayez un log4j.propertiesquelque part sur le classpath, je suggérerais donc d'utiliser:

log4j.logger.org.springframework.transaction=DEBUG
Pascal Thivent
la source
7

Étant donné que vous pouvez accéder aux classes Spring au moment de l'exécution, vous pouvez déterminer l'état de la transaction. Cet article peut vous aider:

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

Michel Gokan
la source
Très cassé, mais essayez: Astuces pour déboguer l'annotation @Transactional de Spring (je ne l'ai pas encore essayé moi-même). Il utilise TransactionSynchronizationManager pour obtenir le statut de la transaction. Le code devrait probablement utiliser une variable locale de thread pour mettre en cache la référence au au isActualTransactionActive()lieu de la récupérer à chaque appel de journalisation.
David Tonhofer
6

Vous pouvez également activer la journalisation JDBC:

log4j.logger.org.springframework.jdbc=DEBUG
Dynamisme
la source
1

Voici un code que j'utilise dans mon implémentation Logback Layout dérivée de ch.qos.logback.core.LayoutBase .

Je crée une variable locale de thread pour stocker la référence à la méthode org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Chaque fois qu'une nouvelle ligne de journal est imprimée, getSpringTransactionInfo()est appelée et renvoie une chaîne d'un caractère qui ira dans le journal.

Références:

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;
}
David Tonhofer
la source