1. 概述

在某些场景下,检测当前是否存在活跃的事务非常有用,比如用于审计、调试或处理没有良好事务规范的复杂代码库。

本文将介绍几种在 Spring 应用中判断事务是否激活的方法。

2. 事务配置准备

要让 Spring 的事务机制生效,首先需要启用事务管理功能。✅ 如果你使用的是 Spring Boot 项目,并且引入了 spring-data-*spring-tx 相关依赖,那么事务管理默认就是开启的。

否则,你需要手动开启事务支持:

  • 在配置类上添加 @EnableTransactionManagement 注解,启用基于注解的事务管理。
  • 提供一个 PlatformTransactionManagerReactiveTransactionManager 的 Bean 实例。这个 Bean 需要依赖一个 DataSource,可以是 H2、MySQL 等常见数据库的实现。

配置完成后,就可以通过 @Transactional 注解来声明事务了。

3. 使用 TransactionSynchronizationManager

Spring 提供了一个非常实用的工具类:TransactionSynchronizationManager。它有一个静态方法 isActualTransactionActive() 可以直接告诉我们当前线程是否有活跃的事务。

来看两个测试用例:

✅ 带有 @Transactional 注解的方法中,调用该方法应返回 true

@Test
@Transactional
public void givenTransactional_whenCheckingForActiveTransaction_thenReceiveTrue() {
    assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
}

❌ 不带事务注解时,应该返回 false

@Test
public void givenNoTransactional_whenCheckingForActiveTransaction_thenReceiveFalse() {
    assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
}

⚠️ 注意:这个方法只能检测当前线程是否处于事务上下文中,不能跨线程使用。

4. 启用 Spring 事务日志

如果只是想在日志中看到事务的开启和提交过程,而不需要编程方式检测,可以简单地在配置文件中启用 Spring 的事务日志:

logging.level.org.springframework.transaction.interceptor = TRACE

开启后,你会看到类似下面的日志输出:

2020-10-02 14:45:07,162 TRACE - Getting transaction for [com.Class.method]
2020-10-02 14:45:07,273 TRACE - Completing transaction for [com.Class.method]

虽然这些日志本身信息不多,但结合你自己的业务日志,就能轻松定位事务边界了。

5. 总结

在这篇文章中我们介绍了两种检测 Spring 事务是否激活的方式:

  • 编程方式:使用 TransactionSynchronizationManager.isActualTransactionActive() 方法。
  • 日志方式:通过开启 Spring 内置的事务日志来观察事务行为。

这两种方法各有适用场景,前者适合用于逻辑控制,后者适合用于调试和监控。

📌 示例代码可以在 GitHub 项目 中找到。


原始标题:Detecting If a Spring Transaction Is Active