Отображение транзакции Spring в журнале


104

Я настроил spring с поддержкой транзакций. Есть ли способ регистрировать транзакции, чтобы убедиться, что я все правильно настроил? Отображение в журнале - хороший способ увидеть, что происходит.

Ответы:


96

в вашем log4j.properties(для альтернативных регистраторов или формата log4j xml, проверьте документы)

В зависимости от вашего менеджера транзакций вы можете установить уровень ведения журнала Spring framework, чтобы он давал вам больше информации о транзакциях. Например, в случае использования JpaTransactionManagerвы устанавливаете

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

(это пакет вашего менеджера транзакций), а также

log4j.logger.org.springframework.transaction=INFO

Если INFOэтого недостаточно, используйтеDEBUG


7
INFOlevel не будет показывать никакой активности tx, это было бы слишком многословно. DEBUGтам будет нужно.
— skaffman

@Bozho У меня JpaTransactionManager, и я хочу отслеживать, когда соединение заимствовано из пула и когда оно было выпущено для конкретной транзакции.
— Али

тогда вам нужно будет изменить конфигурацию ведения журнала для вашего пула соединений
— Божо

что, если мы используем mybatis + slf4j + logback + springboot?
— lily

67

Для меня была добавлена ​​хорошая конфигурация журналирования:

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

Он покажет мне такой журнал:

2012-08-22 18: 50: 00,031 TRACE - Получение транзакции для [com.MyClass.myMethod]

[мои собственные записи журнала из метода com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - Завершение транзакции для [com.MyClass.myMethod]


1
Большой! Нет необходимости иметь всю информацию / журнал отладки / трассировки других пакетов, если это то, что вы ищете: D
— Johanneke

34

Для приложения Spring Boot с application.properties

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

или если вы предпочитаете Yaml ( application.yaml)

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

1
Работает как шарм
— Бен

9

Наиболее интересная информация журнала JtaTransactionManager.java(если этот вопрос все еще касается JtaTransactionManager) регистрируется с DEBUGприоритетом. Предполагая, что у вас есть log4j.propertiesгде-то в пути к классам, я бы предложил использовать:

log4j.logger.org.springframework.transaction=DEBUG

7

Поскольку вы можете получить доступ к классам Spring во время выполнения, вы можете определить статус транзакции. Эта статья может помочь вам:

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


Очень сломано, но попробуйте: Советы по отладке аннотации @Transactional в Spring (сам еще не пробовал). Он использует TransactionSynchronizationManager для получения статуса транзакции. Код, вероятно, должен использовать локальную переменную потока для кеширования ссылки на isActualTransactionActive()вместо извлечения ее при каждом вызове журнала.
— Дэвид Тонхофер

6

Вы также можете включить ведение журнала JDBC:

log4j.logger.org.springframework.jdbc=DEBUG

1

Вот код, который я использую в своей реализации Logback Layout, полученный из ch.qos.logback.core.LayoutBase .

Я создаю локальную переменную потока для хранения ссылки на метод org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive(). Всякий раз, когда печатается новая строка журнала, getSpringTransactionInfo()вызывается, и он возвращает односимвольную строку, которая войдет в журнал.

Ссылки:

Код:

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.