Spring @Transactional 和 Neo4j OGM session.getTransaction()
Spring @Transactional and Neo4j OGM session.getTransaction()
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)
我做错了什么?为什么交易消失了?
这个问题涉及几个问题和主题。我会尝试将它们分解,希望最后一切都有意义。
截至最新版本 Spring Data Neo4j (4.1.x) Spring 的 @Transactional
与 Neo4j OGM 的 Session.getTransaction()
或 Session.beginTransaction()
直接调用时。
在前两个代码块中,您完全直接管理 OGM 会话生命周期。 Spring 此时根本不参与,正如您所说,它按预期执行。
在您更新的第三个代码块中,您现在期望您手动打开的会话与您的 Spring 托管 DAO 一起工作。这里会发生什么取决于你在 SDN 上使用的 Neo4j 驱动程序,但本质上是因为你的 DAO 有 @Transactional
注释,Spring 将拦截调用并在顶部自行开始一个全新的事务您手动管理的那个。在这一点上,我们不能对行为做出任何保证,但最简单的解释是说这将是意外的(同样,取决于所使用的驱动程序)。
那么如何解决这个问题?
我假设您想使用 Spring 事务和 Spring 数据 Neo4j。如果是这种情况,您将要开始:
- 更改您的 DAO 以使用 Spring 数据存储库。这为您提供了许多免费的持久性功能,如查找、保存、删除等。
- 将
@Transactional
注释放在您要完成的工作单元周围。您可能有一个调用 userRepository.findByUserName()
、修改该用户并调用 userRepository.save(user)
的方法。在 Web 环境中,这通常是某种服务方法。
- 删除任何手动启动或结束 OGM 会话事务的代码。
您可以找到 very short code sample here and a longer code sample here.
更comprehensive guide can also be found here.
在 Spring Data Neo4j 4.2.x 中,我们希望引入一些更强大和更友好的 @Transactional
行为,因此请随时发布该更新。
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)
我做错了什么?为什么交易消失了?
这个问题涉及几个问题和主题。我会尝试将它们分解,希望最后一切都有意义。
截至最新版本 Spring Data Neo4j (4.1.x) Spring 的 @Transactional
与 Neo4j OGM 的 Session.getTransaction()
或 Session.beginTransaction()
直接调用时。
在前两个代码块中,您完全直接管理 OGM 会话生命周期。 Spring 此时根本不参与,正如您所说,它按预期执行。
在您更新的第三个代码块中,您现在期望您手动打开的会话与您的 Spring 托管 DAO 一起工作。这里会发生什么取决于你在 SDN 上使用的 Neo4j 驱动程序,但本质上是因为你的 DAO 有 @Transactional
注释,Spring 将拦截调用并在顶部自行开始一个全新的事务您手动管理的那个。在这一点上,我们不能对行为做出任何保证,但最简单的解释是说这将是意外的(同样,取决于所使用的驱动程序)。
那么如何解决这个问题?
我假设您想使用 Spring 事务和 Spring 数据 Neo4j。如果是这种情况,您将要开始:
- 更改您的 DAO 以使用 Spring 数据存储库。这为您提供了许多免费的持久性功能,如查找、保存、删除等。
- 将
@Transactional
注释放在您要完成的工作单元周围。您可能有一个调用userRepository.findByUserName()
、修改该用户并调用userRepository.save(user)
的方法。在 Web 环境中,这通常是某种服务方法。 - 删除任何手动启动或结束 OGM 会话事务的代码。
您可以找到 very short code sample here and a longer code sample here.
更comprehensive guide can also be found here.
在 Spring Data Neo4j 4.2.x 中,我们希望引入一些更强大和更友好的 @Transactional
行为,因此请随时发布该更新。