Отображение транзакции 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.