Mostrando una transacción de Spring en el registro

102

Configuré Spring con soporte transaccional. ¿Hay alguna forma de registrar transacciones solo para asegurarme de que configuré todo correctamente? Mostrar en el registro es una buena forma de ver lo que está sucediendo.

cometa
fuente

Respuestas:

96

en su log4j.properties(para registradores alternativos o formato xml de log4j, consulte los documentos)

Dependiendo de su administrador de transacciones, puede establecer el nivel de registro del marco de Spring para que le brinde más información sobre las transacciones. Por ejemplo, en caso de usar JpaTransactionManager, establece

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

(este es el paquete de su administrador de transacciones), y también

log4j.logger.org.springframework.transaction=INFO

Si INFOno es suficiente, useDEBUG

Bozho
fuente
7
INFOlevel no mostrará ninguna actividad tx en absoluto, sería demasiado detallado. DEBUGserá necesario allí.
skaffman
@Bozho Tengo JpaTransactionManager y quiero monitorear cuándo se toma prestada una conexión del grupo y cuándo se libera para una transacción específica.
Ali
entonces necesitaría cambiar la configuración de registro para su grupo de conexiones
Bozho
¿Qué pasa si usamos mybatis + slf4j + logback + springboot?
lirio
66

Para mí, una buena configuración de registro para agregar fue:

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

Me mostrará un registro así:

2012-08-22 18: 50: 00,031 TRACE - Obteniendo transacción para [com.MyClass.myMethod]

[mis propias declaraciones de registro del método com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Completando transacción para [com.MyClass.myMethod]

Sander S.
fuente
1
¡Excelente! No es necesario tener toda la información / depuración / registro de seguimiento de otros paquetes, cuando esto es lo que está buscando: D
Johanneke
31

Para la aplicación Spring Boot con application.properties

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

o si prefieres Yaml ( application.yaml)

logging:
   level:
      org.springframework.orm.jpa: DEBUG
      org.springframework.transaction: DEBUG
MariuszS
fuente
1
Funciona como un encanto
Ben
9

La información de registro más interesante de JtaTransactionManager.java(si esta pregunta todavía es sobre JtaTransactionManager) se registra con DEBUGprioridad. Suponiendo que tenga un log4j.propertieslugar en la ruta de clases, le sugiero que use:

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

Debido a que puede acceder a las clases de Spring en tiempo de ejecución, puede determinar el estado de la transacción. Este artículo puede ayudarlo a:

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

Michel Gokan
fuente
Muy roto, pero intente: Consejos para depurar la anotación @Transactional de Spring (todavía no lo he probado). Utiliza TransactionSynchronizationManager para obtener el estado de la transacción. El código probablemente debería usar una variable local de subproceso para almacenar en caché la referencia a en isActualTransactionActive()lugar de recuperarla en cada llamada de registro.
David Tonhofer
6

También puede habilitar el registro JDBC:

log4j.logger.org.springframework.jdbc=DEBUG
Energía
fuente
1

Aquí hay un código que utilizo en mi implementación de Logback Layout derivado de ch.qos.logback.core.LayoutBase .

Creo una variable local de hilo para almacenar la referencia al método org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Siempre que se imprime una nueva línea de registro, getSpringTransactionInfo()se llama y devuelve una cadena de un carácter que se incluirá en el registro.

Referencias:

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
fuente