调用flush与@Transactional后,数据库仍未成功保存数据
原生JPA插入无异常但数据未入库的排查方案
问题现象
通过Spring JPA原生查询执行INSERT操作,全程无异常抛出,但数据库中始终看不到新增的数据。已尝试调用flush()方法,且添加了@Transactional注解(同时混用了javax和Spring版本的注解),但问题依旧,也没有相关日志可用于排查持久化环节的问题。
涉及代码
DAO层代码
public interface DBConnection extends JpaRepository<Enitty, Long> { String query = "INSERT INTO My_table (MESSAGE_CODE, MESSAGE, LANGUAGE, ID) VALUES(?1,?2,?3,?4)"; @Modifying @Transactional @Query(value = query, nativeQuery = true) void save(String a, String r, String t, String s); }
调用层代码
@Transactional private void saveToDB(List<List<String>> records) { int count = 0; for (List<String> record : records) { try { dbConnection.save(record.get(0), record.get(1), record.get(2), record.get(3)); dbConnection.flush(); } catch (DataIntegrityViolationException e) { count++; System.out.println("element probably exists " + record); } catch (Exception e) { System.out.println("Error record is " + record); e.printStackTrace(); } } System.out.println(count); }
可能的原因及解决方法
- 注解混用冲突:同时使用javax和Spring的
@Transactional注解会导致事务管理逻辑混乱,建议统一使用Spring的org.springframework.transaction.annotation.Transactional注解。 - 私有方法事务失效:Spring事务代理默认仅对公共(public)方法生效,私有方法上的
@Transactional注解不会被AOP代理识别,事务根本未开启。需将saveToDB改为public方法,这是最直接的解决方案。 - 参数绑定不匹配:核对参数顺序与INSERT语句的字段顺序是否完全对应,确认
record.get(0)到record.get(3)的值是否正确映射到MESSAGE_CODE、MESSAGE、LANGUAGE、ID字段。若ID是自增主键,手动传入值可能导致隐性冲突(部分数据库会静默忽略或使用默认值)。 - 隐性事务回滚:即使未捕获到异常,也可能存在未被捕获的RuntimeException触发事务回滚。建议开启Spring事务日志排查:
通过日志确认事务的开启、提交或回滚状态。logging.level.org.springframework.transaction=DEBUG logging.level.org.springframework.orm.jpa=DEBUG - flush()作用局限:
flush()仅将持久化上下文的变更同步到数据库,若事务未提交,数据库变更会处于未提交状态(受数据库隔离级别影响)。核心问题还是事务是否真正完成提交。
内容的提问来源于stack exchange,提问作者Akash Jain
相关产品推荐
相关产品推荐

