Spring @Transactional and Neo4j OGM session.getTransaction()



Spring org.springframework.transaction.annotation.Transactional注释和 Neo4j OGM org.neo4j.ogm.session.Session.getTransaction()方法之间的相关性是什么?

我正在尝试通过用 Spring @Transactional 注释的方法内部的session.getTransaction()访问当前事务,但总是为空。

我在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,然后为空...由于某种原因,事务在提交之前消失。

这是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)

我做错了什么?为什么交易消失了?

这个问题有几个问题和主题。我会尝试分解它们,希望最后这一切都有意义。

从Spring Data Neo4j(4.1.x)的最新版本开始,Spring的@Transactional与直接调用时Neo4j OGM的Session.getTransaction()Session.beginTransaction()之间没有相关性。

在前两个代码块中,您将直接完全管理 OGM 会话生命周期。此时 Spring 根本不参与,正如您所说,它按预期执行。

在更新的第三个代码块中,您现在期望手动打开的会话能够与 Spring 托管的 DAO 一起使用。这里会发生什么取决于您与SDN一起使用的Neo4j驱动程序,但本质上是因为您的DAO具有@Transactional注释,Spring将拦截呼叫并在您手动管理的基础上自行启动全新的事务。在这一点上,我们无法对行为做出任何保证,但最简单的解释是说它会出乎意料(再次,取决于使用的驱动程序)。

那么如何解决这个问题呢?

我假设你想使用 Spring Transactions 和 Spring Data Neo4j。如果是这种情况,您需要从以下方面开始:

  1. 更改您的 DAO 以使用 Spring 数据存储库。这为您提供了许多免费的持久性功能,例如查找器,保存,删除等。
  2. @Transactional注释放在要完成的工作单元周围。您可能有一个调用 userRepository.findByUserName() 的方法,修改该用户并调用 userRepository.save(user) 。在 Web 环境中,这通常是某种服务方法。
  3. 删除手动启动或结束 OGM 会话事务的任何代码。
您可以在此处找到

非常短的代码示例,在此处找到较长的代码示例。

更全面的指南也可以在这里找到。

在Spring Data Neo4j 4.2.x中,我们希望引入一些更强大,更友好的@Transactional行为,因此请继续发布该更新。

相关内容

  • 没有找到相关文章

最新更新