使用Testcontainers连接MSSQL时测试卡住问题求助
问题分析与解决办法
核心问题点
事务隔离导致数据不可见+阻塞
@DataJpaTest默认会为测试方法开启事务,且测试结束后自动回滚。你通过Spring Data JPA插入的数据处于未提交状态,此时用DriverManager创建的外部独立连接无法读取到这些数据,若事务持有数据库锁,还会导致外部查询卡住。Testcontainers等待条件配置错误
连续调用两次.waitingFor()会覆盖前一个条件,而非组合条件。这可能导致容器未完全就绪就启动测试,引发连接异常或阻塞。手动连接未适配Spring事务上下文
直接使用DriverManager创建连接脱离了Spring的数据源管理,既无法复用已有连接,也无法感知Spring事务的状态。
具体修复方案
方案1:调整测试事务行为
在测试方法上添加@Transactional(propagation = Propagation.NOT_SUPPORTED),让测试方法脱离Spring事务管理,JPA操作的数据会立即提交,外部连接可正常读取:
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Test @Transactional(propagation = Propagation.NOT_SUPPORTED) void name() { // 原有测试代码... }
方案2:修正Testcontainers等待条件
用Wait.allOf()组合监听端口和日志的条件,确保容器完全就绪:
static MSSQLServerContainer<?> mssqlserver = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest") .acceptLicense() .waitingFor(Wait.allOf( Wait.forListeningPort(), Wait.forLogMessage(".*Started.*", 1) ));
方案3:复用Spring数据源查询(推荐)
放弃手动创建DriverManager连接,注入Spring的JdbcTemplate来查询,这样能复用已有数据源和事务上下文,避免连接问题:
@Autowired private JdbcTemplate jdbcTemplate; @Test void name() { // 原有JPA操作代码... // 替换手动连接查询为JdbcTemplate jdbcTemplate.query("SELECT id, task FROM todos", (resultSet, rowNum) -> { int id = resultSet.getInt("id"); String task = resultSet.getString("task"); System.out.println("ID: " + id + ", Task: " + task); return null; }); }
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

