在日志中显示Spring事务


102

我为Spring配置了事务支持。有什么方法可以记录交易记录,只是为了确保我正确设置了所有内容?在日志中显示是查看正在发生的事情的好方法。

Answers:


95

在您log4j.properties的文档中(对于其他记录器或log4j的xml格式,请检查文档)

根据事务管理器的不同,您可以设置spring框架的日志记录级别,以便为您提供有关事务的更多信息。例如,如果使用JpaTransactionManager,您可以设置

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

(这是您的交易经理的软件包),以及

log4j.logger.org.springframework.transaction=INFO

如果INFO还不够,请使用DEBUG


7
INFO级别根本不显示任何tx活动,这太冗长了。DEBUG在那里是必要的。
skaffman

@Bozho我有JpaTransactionManager,我想监视何时从池借用连接以及何时为特定事务释放连接。
阿里

那么您需要更改连接池的日志记录配置
Bozho

如果我们使用mybatis + slf4j + logback + springboot怎么办?
百合

66

对我来说,要添加的一个好的日志记录配置是:

log4j.logger.org.springframework.transaction.interceptor =跟踪

它会显示如下日志:

2012-08-22 18:50:00,031跟踪-获取[com.MyClass.myMethod]的交易

[来自方法com.MyClass.myMethod的我自己的日志语句]

2012-08-22 18:50:00,142跟踪-完成[com.MyClass.myMethod]的交易


1
大!当您正在寻找的时候,无需拥有其他软件包的所有信息/调试/跟踪日志:D
Johanneke

31

对于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
像魅力一样工作
Ben


7

因为您可以在运行时访问Spring类,所以可以确定事务状态。本文可以为您提供帮助:

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


很坏,但是可以尝试:调试Spring的@Transactional注释的技巧(我自己还没有尝试过)。它使用TransactionSynchronizationManager获取事务状态。该代码可能应该使用线程局部变量来缓存对的引用,isActualTransactionActive()而不是在每次日志记录调用时都对其进行检索。
David Tonhofer

6

您还可以启用JDBC日志记录:

log4j.logger.org.springframework.jdbc=DEBUG

1

下面是一些代码我在衍生的logback布局实现中使用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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.