我配置了带有事务支持的Spring。是否有任何方法可以记录事务,以确保我正确设置了所有内容?在日志中显示是观察发生情况的好方法。
我配置了带有事务支持的Spring。是否有任何方法可以记录事务,以确保我正确设置了所有内容?在日志中显示是观察发生情况的好方法。
在您的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 = trace
对于有 application.properties
的 Spring Boot 应用程序
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
你也可以启用JDBC日志:
log4j.logger.org.springframework.jdbc=DEBUG
如果这个问题仍然涉及到JtaTransactionManager
,那么JtaTransactionManager.java
的最有趣的日志信息将以DEBUG
优先级记录。假设您在类路径上的某个地方有一个log4j.properties
文件,因此我建议使用:
log4j.logger.org.springframework.transaction=DEBUG
这是我在我的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;
}
由于您可以在运行时访问Spring类,因此可以确定事务状态。
isActualTransactionActive()
的引用,而不是在每个日志调用中检索它。 - David Tonhofer