1

问题

在spring框架没有事务的情况下,通过hibernate的session.save(entity),无法将数据持久化至数据库中,即使强制刷新后(flush())后也同样如此。

原因

混淆了spring框架中事务和mysql事务的概念。对于增删改操作,必须commit后才能持久化至mysql数据库。若不commit,只有在同一个连接中才能看到最新的更改,对其他连接不可见。

扩展

Hibernate的flush

执行时会清除session缓存并向数据库发送SQL语句并执行,但此时如果数据库当前存在一个事务,数据库会先将这些SQL语句缓存起来,那么此时在数据库中是无法看到SQL语句执行结果的。除非执行commit提交了事务。只要没有执行commit()方法,就能通过rollback()方法进行回滚。

Hibernate的commit

执行时会先隐式调用flush()方法,再提交事务。执行之后无法rollback()进行回滚。即commit操作才是真正的将实体数据持久化至数据库。

总结

通过hibernate进行数据库连接时,autocommit默认是false,因此仅仅做flush()是无法将数据持久化至数据库的,必须显式调用commit方法。
而如果使用jdbcTemplate进行数据库连接的话,无需显式执行commit方法,因为此时autocommit默认为true。通过以下代码验证之:

Connection conn = DriverManager.getConnection(JdbcTest.URL, JdbcTest.USER, JdbcTest.PWD); // 通过JDBC进行连接
SessionFactory sFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); 
Session session = sFactory.openSession(conn); // 使用jdbc的连接初始化hibernate的session
System.out.println(session.connection().getAutoCommit()); // autoCommit默认为true

skyarthur
1.6k 声望1.3k 粉丝

技术支持业务,技术增强业务,技术驱动业务