在springboot中Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@c3c1995]
时间: 2025-05-23 13:21:07 浏览: 30
### Spring Boot 中关闭非事务性 SqlSession 的解决方案
在 Spring Boot 集成 MyBatis 的场景下,当使用非事务性的 `SqlSession` 时,可能会遇到资源未正确释放的问题。这是因为默认情况下,Spring 和 MyBatis 的集成机制会在事务上下文中管理 `SqlSession` 生命周期[^2]。如果某些操作不在事务范围内,则可能导致 `SqlSession` 不被自动关闭。
#### 解决方案概述
为了确保非事务性 `SqlSession` 能够正常关闭并释放资源,可以采取以下措施:
1. **手动控制 SqlSession 生命周期**
如果需要显式地创建和关闭 `SqlSession`,可以通过注入 `SqlSessionFactory` 来实现。这种方式允许开发者完全掌控 `SqlSession` 的生命周期。
```java
@Service
public class CustomTestService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public void executeNonTransactionalQuery() {
try (SqlSession session = sqlSessionFactory.openSession()) {
TestMapper mapper = session.getMapper(TestMapper.class);
List<TestEntity> result = mapper.selectByCondition("example");
System.out.println(result);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
```
上述代码通过 `sqlSessionFactory.openSession()` 显式打开新的 `SqlSession` 并将其封装在一个 `try-with-resources` 块中,从而确保即使发生异常也能安全关闭 `SqlSession`[^2]。
2. **调整 MyBatis-Spring 配置**
默认情况下,MyBatis-Spring 使用单线程模式下的共享 `SqlSession` 实现性能优化。然而,在高并发环境下或特定业务逻辑需求下,可能需要禁用这种行为以避免潜在的资源泄漏风险。可以在配置文件中设置如下参数:
```properties
mybatis.configuration.use-default-executor-type=true
spring.datasource.continue-on-error=false
```
此外,还可以自定义 `ExecutorType` 类型为 BATCH 或 REUSE 模式来进一步提升效率的同时减少内存占用[^4]。
3. **验证数据源连接池状态**
数据库连接池(如 Druid、HikariCP)对于维护 JDBC 连接至关重要。如果发现存在大量空闲连接未能及时归还至池子中,可能是由于 `SqlSession` 关闭不彻底引起的连锁反应。因此建议定期监控连接池健康状况并通过日志排查问题所在位置[^3]。
4. **启用调试日志辅助诊断**
设置适当级别的日志记录可以帮助快速定位哪些地方出现了遗漏关闭的情况。例如修改 application.properties 文件增加以下内容即可开启 SQL 执行跟踪功能:
```properties
logging.level.org.springframework.jdbc=DEBUG
logging.level.com.example.mapper=TRACE
```
---
### 示例代码展示
以下是基于上述理论的一个完整例子演示如何处理非事务环境下的 `SqlSession`:
```java
@Service
public class NonTransactionalService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
/**
* 查询指定条件的数据集合.
*/
public List<UserInfo> findUsers(String condition){
try(SqlSession session = this.sqlSessionFactory.openSession(false)){
UserInfoMapper mapper = session.getMapper(UserInfoMapper.class);
return mapper.findByCondition(condition);
}// 自动触发 close()
}
}
```
注意这里传递了一个布尔值 false 给 openSession 方法表示不需要启动任何隐含的事物支持.
---
### 总结说明
综上所述,针对 Spring Boot 结合 MyBatis 场景中存在的 “non-transactional sqlSession not closed properly” 问题,推荐采用以上提到的手动管理方式配合合理的框架配置策略加以应对。这样既能保障程序运行稳定性又能提高开发灵活性。
阅读全文
相关推荐


















