Answers:
在您log4j.properties
的文档中(对于其他记录器或log4j的xml格式,请检查文档)
根据事务管理器的不同,您可以设置spring框架的日志记录级别,以便为您提供有关事务的更多信息。例如,如果使用JpaTransactionManager
,您可以设置
log4j.logger.org.springframework.orm.jpa=INFO
(这是您的交易经理的软件包),以及
log4j.logger.org.springframework.transaction=INFO
如果INFO
还不够,请使用DEBUG
对我来说,要添加的一个好的日志记录配置是:
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]的交易
对于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
JtaTransactionManager.java
(如果该问题仍然与有关JtaTransactionManager
)的最有趣的日志信息将DEBUG
优先记录。假设您log4j.properties
在类路径中有某个位置,因此建议使用:
log4j.logger.org.springframework.transaction=DEBUG
因为您可以在运行时访问Spring类,所以可以确定事务状态。本文可以为您提供帮助:
isActualTransactionActive()
而不是在每次日志记录调用时都对其进行检索。
下面是一些代码我在衍生的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;
}
INFO
级别根本不显示任何tx活动,这太冗长了。DEBUG
在那里是必要的。