Mostrando uma transação Spring no log

102

Configurei a mola com suporte transacional. Existe alguma maneira de registrar transações apenas para garantir que configurei tudo corretamente? Mostrar no log é uma boa maneira de ver o que está acontecendo.

cometta
fonte

Respostas:

96

em seu log4j.properties(para loggers alternativos ou formato xml do log4j, verifique os documentos)

Dependendo do seu gerenciador de transações, você pode definir o nível de registro do framework spring para que ele forneça mais informações sobre as transações. Por exemplo, no caso de usar JpaTransactionManager, você define

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

(este é o pacote do seu gerenciador de transações), e também

log4j.logger.org.springframework.transaction=INFO

Se INFOnão for o suficiente, useDEBUG

Bozho
fonte
7
INFOnível não mostrará nenhuma atividade tx, seria muito prolixo. DEBUGserá necessário lá.
skaffman
@Bozho Eu tenho JpaTransactionManager e quero monitorar quando uma conexão é emprestada do pool e quando foi liberada para uma transação específica.
Ali
então você precisaria alterar a configuração de registro para seu pool de conexão
Bozho
e se usarmos mybatis + slf4j + logback + springboot?
lily
66

Para mim, uma boa configuração de registro para adicionar foi:

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

Ele vai me mostrar o log assim:

2012-08-22 18: 50: 00,031 TRACE - Obtendo transação para [com.MyClass.myMethod]

[minhas próprias declarações de log do método com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Concluindo transação para [com.MyClass.myMethod]

Sander S.
fonte
1
Ótimo! Não há necessidade de ter todos os logs de informações / depuração / rastreamento de outros pacotes, quando é isso que você está procurando: D
Johanneke
31

Para aplicação Spring Boot com application.properties

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

ou se você preferir Yaml ( application.yaml)

logging:
   level:
      org.springframework.orm.jpa: DEBUG
      org.springframework.transaction: DEBUG
MariuszS
fonte
1
Funciona como um encanto
Ben,
9

Informações de registro mais interessantes de JtaTransactionManager.java (se esta questão ainda for sobre JtaTransactionManager) são registradas em DEBUGprioridade. Supondo que você tenha um log4j.propertieslugar no caminho de classe, sugiro usar:

log4j.logger.org.springframework.transaction=DEBUG
Pascal Thivent
fonte
7

Como você pode acessar classes Spring em tempo de execução, pode determinar o status da transação. Este artigo pode ajudá-lo:

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

Michel Gokan
fonte
Muito quebrado, mas tente: Dicas para depurar a anotação @Transactional do Spring (ainda não tentei). Ele usa TransactionSynchronizationManager para obter o status da transação. O código provavelmente deve usar uma variável de segmento local para armazenar em cache a referência ao, em isActualTransactionActive()vez de recuperá-la em cada chamada de registro.
David Tonhofer,
6

Você também pode habilitar o registro JDBC:

log4j.logger.org.springframework.jdbc=DEBUG
Pep
fonte
1

Aqui está algum código que eu uso na minha implementação de Layout de Logback, derivado de ch.qos.logback.core.LayoutBase .

Eu crio uma variável thread-local para armazenar a referência ao método org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Sempre que uma nova linha de log é impressa,getSpringTransactionInfo() é chamada e retorna uma string de um caractere que irá para o log.

Referências:

Código:

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
fonte