【问题标题】:Spring @Transactional and Neo4j OGM session.getTransaction()Spring @Transactional 和 Neo4j OGM session.getTransaction()
【发布时间】:2016-07-12 20:52:43
【问题描述】:

Springorg.springframework.transaction.annotation.Transactional注解和Neo4j OGMorg.neo4j.ogm.session.Session.getTransaction()方法有什么关系。

我正在尝试通过 session.getTransaction() 在使用 Spring @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)

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

【问题讨论】:

    标签: neo4j spring-data-neo4j spring-transactions spring-data-neo4j-4 neo4j-ogm


    【解决方案1】:

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

    在 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 Data Repositories。这为您提供了许多免费的持久性功能,例如查找器、保存、删除等。
    2. @Transactional 注释放在要完成的工作单元周围。您可能有一个调用userRepository.findByUserName() 的方法,修改该用户并调用userRepository.save(user)。在网络环境中,这通常是某种服务方法。
    3. 删除任何手动启动或结束 OGM 会话事务的代码。

    您可以找到very short code sample herelonger code sample here

    多一个comprehensive guide can also be found here

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      • 2021-03-26
      • 2018-07-19
      • 2017-03-18
      • 2022-10-14
      相关资源
      最近更新 更多