Spring Data Neo4j 6.1.1中@Transactional注解未生效,数据库更新提前可见的问题咨询
你遇到的问题主要和SDN 6的事务机制、方法可见性以及直接使用Neo4j Driver会话有关,我来帮你一步步排查解决:
1. 确保@Transactional标注在public方法上
Spring的AOP代理(不管是JDK动态代理还是CGLIB)默认只会对public方法的@Transactional注解生效。你代码里的method()是默认包访问权限(没有public修饰符),这会导致Spring无法为它创建事务代理——每个template.save、repository.save调用都会开启独立的自动提交事务,所以你会看到数据提前提交到数据库。
修改方法为public即可:
@Transactional public void method() { // 你的原有代码逻辑 }
2. 避免直接使用Neo4j Driver的独立会话
你代码里直接调用driver.session().run(...),这个操作会绕过Spring管理的事务上下文,创建一个完全独立的Neo4j会话,而这个会话默认是自动提交模式的。这也是你在方法执行过程中就能看到数据库更新的原因之一——这个独立会话的查询已经能看到其他自动提交事务的修改了。
如果要在Spring事务中执行自定义Cypher,应该用Neo4jTemplate的execute方法,它会复用当前Spring管理的事务会话:
// 替换原来的driver.session()代码 Long count = template.execute((session) -> { Result result = session.run("Match(n) return count(n) as count"); return result.single().get("count").asLong(); }); System.out.println("Entity Count: " + count);
3. 确认Spring事务管理器配置正确
虽然Spring Boot会自动配置Neo4j事务管理器,但你可以简单检查:
- 确保主配置类上隐含了
@EnableTransactionManagement(Spring Boot自动配置会默认添加,除非你自定义了配置类) - 没有自定义的事务管理器覆盖了默认的
Neo4jTransactionManager
4. 理解SDN 6的事务提交时机
SDN 6和旧版本OGM的事务处理逻辑不同:在Spring事务上下文里,所有通过Neo4jTemplate和Repository的操作都会延迟到事务提交时统一执行(除非手动调用flush)。但如果没有Spring事务(比如方法没被代理),每个操作都会开启独立的自动提交事务,这就是你看到数据提前出现的核心原因。
修正以上几点后,你的method()方法会被Spring事务代理管理,所有操作都会在方法执行完毕后统一提交,中间过程的修改不会被其他会话看到(除非调整事务隔离级别)。
内容的提问来源于stack exchange,提问作者Shayan

