Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4b425577]
时间: 2023-11-07 07:43:53 浏览: 82
这条信息通常出现在使用 MyBatis 框架的时候,意味着当前 SqlSession 没有开启事务或者没有正确地关闭 SqlSession。建议在使用完 SqlSession 后,手动关闭它,以避免潜在的资源泄漏和错误。可以使用 try-with-resources 或者 finally 块来确保关闭 SqlSession。如果是使用 Spring 等框架,可以考虑使用声明式事务来管理 SqlSession。
相关问题
Creating a new SqlSession Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@7aad12b6] will be managed by Spring Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] from current transaction Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@462f5b5c] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@bd09874] was not registered for synchronization because synchronization is not active JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@7aad12b6] will not be managed by Spring Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@bd09874]
### Spring 中 SqlSession 和事务同步的管理
在 Spring 集成 MyBatis 的场景下,`SqlSession` 的管理和事务同步由 `SqlSessionTemplate` 完成。以下是具体的过程及其日志解释:
#### 1. **SqlSession 创建**
当应用程序需要访问数据库时,Spring 使用 `SqlSessionUtils.getSession()` 方法来获取一个 `SqlSession` 实例。如果当前线程已经存在一个与事务绑定的 `SqlSession`,则直接返回该实例;否则,会创建一个新的 `SqlSession` 并将其注册到事务中[^3]。
相关日志:
- `Creating a new SqlSession`: 表明正在创建一个新的 `SqlSession` 实例。
```java
// 获取 SqlSession 的过程
SqlSession session = SqlSessionUtils.getSqlSession(sqlSessionFactory, executorType, exceptionTranslator);
```
#### 2. **事务注册 (Synchronization Registration)**
如果启用了事务管理,则新创建的 `SqlSession` 将被注册到当前事务上下文中。这一步确保了 `SqlSession` 能够参与到 Spring 的事务控制中,比如提交或回滚操作[^1]。
相关日志:
- `SqlSession [...] was not registered for synchronization because synchronization is not active`: 这表明当前环境未启用事务同步功能,因此不会将 `SqlSession` 注册到事务中。
#### 3. **SQL 执行与提交**
对于修改型的操作(如 `insert`, `update`, 或 `delete`),MyBatis 默认情况下不会自动提交更改。只有显式调用 `sqlSession.commit()` 或者通过 Spring 的声明式事务管理完成提交时才会生效[^5]。
相关日志:
- 如果使用的是 JDBC 类型的事务管理器 (`<transactionManager type="JDBC"/>`),那么连接将由 Spring 控制其生命周期,并且会在事务结束时决定是否提交或回滚。
#### 4. **事务注销与关闭**
一旦业务逻辑执行完毕或者事务完成,Spring 会负责释放资源并关闭 `SqlSession`。如果是非事务性的 `SqlSession`,它会被立即关闭;而对于参与事务的 `SqlSession`,它的关闭时机取决于事务的状态(成功提交还是失败回滚)[^2]。
相关日志:
- `Closing non transactional SqlSession [...]`: 显示了一个非事务性 `SqlSession` 正在被正常关闭。
---
### 示例代码展示
以下是一个简单的配置和使用案例,展示了如何集成 MyBatis 和 Spring 来处理事务和 `SqlSession` 管理:
```xml
<!-- mybatis-config.xml -->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
```
```java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void addUser(User user) {
try {
userMapper.insertUser(user); // 插入数据
} catch (Exception e) {
throw new RuntimeException("Error while adding user", e);
}
}
}
```
在这里,`UserMapper` 是基于 MyBatis 动态代理生成的接口,所有的 CRUD 操作都交给了底层的 `SqlSessionTemplate` 处理。
---
### 总结
Spring 对于 `SqlSession` 的管理主要依赖于 `SqlSessionTemplate`,它可以无缝地融入 Spring 的事务管理体系之中。开发者无需关心具体的资源分配和清理工作,而是专注于编写核心业务逻辑即可。与此同时,理解这些日志可以帮助排查潜在问题,例如事务未正确启动、资源泄漏等情况。
---
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@41318e80] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@41318e80] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@41318e80] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@41318e80]
### MyBatis 中事务提交和关闭 SqlSession 的日志信息
在 MyBatis 框架下,当执行数据库操作时,`SqlSession` 对象扮演着至关重要的角色。它不仅负责管理与数据库之间的会话连接,还承担了事务控制的任务。
对于 `commit()` 和 `close()` 方法调用的日志记录行为,在默认情况下,MyBatis 使用 SLF4J 或 Log4j 这样的日志框架来输出调试信息[^1]。具体来说:
- 当成功完成一次事务提交 (`sqlSession.commit()`) 后,如果启用了相应的日志级别(通常是 DEBUG),则会在日志文件中看到类似于 `"Committing JDBC Connection"` 的消息。
- 关闭 `SqlSession` 实例(`sqlSession.close()`) 之前,同样会有对应的日志条目表明正在释放资源以及结束当前会话。这通常表现为诸如 `"Closing non transactional SqlSession"` 或者更详细的描述说明已经断开了与数据源的链接并清理了内部状态的信息。
为了确保能够捕获这些日志事件,应用程序应当配置适当级别的日志过滤器,并指定目标位置保存日志文件。此外,通过调整 mybatis-config.xml 文件中的 `<settings>` 部分可以进一步定制化日志的行为模式,比如启用或禁用延迟加载等功能特性也会影响最终产生的日志内容[^3]。
```xml
<configuration>
<!-- other settings -->
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>
</configuration>
```
上述 XML 片段展示了如何设定使用 SLF4J 作为底层日志实现的方式之一。当然也可以选择其他支持的日志库如 LOG4J 等取决于项目需求和个人偏好。
阅读全文
相关推荐












