Spring org.springframework.transaction.annotation.Transactional
注释与Neo4j OGM org.neo4j.ogm.session.Session.getTransaction()
方法之间的相关性是什么。
我试图通过使用Spring session.getTransaction()
注释的方法中的@Transactional
访问当前事务,但始终为null。
我在Spring MVC RestController方法中添加了以下代码:
Transaction tx = session.beginTransaction();
try {
for (int i = 0; i < 10; i++) {
initializeNode(node);
}
}
tx.commit();
} catch (Throwable th) {
logger.error("Error while inserting mock data", th);
th.printStackTrace();
} finally {
tx.close();
}
以下方法:
private void initializeNode(TestNode node) {
System.out.println(session.getTransaction());
}
它打印当前的tx - 到目前为止一切正常。
但是在以下方法的情况下:
private void initializeNode(TestNode node) {
System.out.println(session.getTransaction());
User admin = userDao.findByUsername("admin");
}
第一次打印当前tx然后null ...由于某种原因,事务在提交之前消失..
这是findByUsername
方法:
@Service
@Transactional
public class UserDaoImpl implements UserDao {
@Override
@Transactional(readOnly = true)
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
...
}
在提交之后,我得到以下异常:
org.neo4j.ogm.exception.TransactionManagerException: Transaction is not current for this thread
at org.neo4j.ogm.session.transaction.DefaultTransactionManager.commit(DefaultTransactionManager.java:100)
at org.neo4j.ogm.transaction.AbstractTransaction.commit(AbstractTransaction.java:83)
at org.neo4j.ogm.drivers.embedded.transaction.EmbeddedTransaction.commit(EmbeddedTransaction.java:77)
我做错了什么?为什么交易消失了?
答案 0 :(得分:6)
这个问题中有几个问题和主题。我会试着打破它们,希望最终它们都有意义。
从Spring Data Neo4j(4.1.x)的最新版本开始,Spring @Transactional
和Neo4j OGM Session.getTransaction()
或{{1}之间没有相关性。直接调用时。
在前两个代码块中,您可以直接完全管理OGM会话生命周期。在这一点上,Spring根本就没有参与,正如你所说的那样,它按预期执行。
在更新的第三个代码块中,您现在希望手动打开的会话可以使用Spring托管DAO。这里会发生什么取决于您使用SDN的Neo4j驱动程序,但主要是因为您的DAO具有Session.beginTransaction()
注释,Spring将拦截该呼叫并在您自己的基础上开始全新的交易手动管理。此时,我们无法对行为做出任何保证,但最简单的解释是说它会出乎意料(再次,取决于使用的驱动程序)。
那你怎么解决这个问题?
我假设你想要使用Spring Transactions和Spring Data Neo4j。如果是这种情况,您需要从以下开始:
@Transactional
注释放在您想要完成的工作单元周围。您可能有一个方法调用@Transactional
,修改该用户并调用userRepository.findByUserName()
。在Web环境中,这通常是某种服务方法。您可以找到very short code sample here和longer code sample here。
更多comprehensive guide can also be found here。
在Spring Data Neo4j 4.2.x中,我们希望引入一些更强大且更友好的userRepository.save(user)
行为,以便继续发布该更新。