2016-11-14 131 views
1

当在SDN 4.1.X中使用prototype作用域Session@Transactional注释时,我看到以下情况除外:org.neo4j.ogm.exception.TransactionManagerException:当原型范围中使用会话时,“该交易对于该线程不是当前交易”

org.neo4j.ogm.exception.TransactionManagerException: "Transaction is not current for this thread" 

我最近升级我的春节,引导项目SDN 4.1.X和Neo4j的OGM 2.0.3。看起来,当启动多个Session时(由于作用域为prototypeDefaultTransactionManager在提交期间无法找到先前打开的事务的引用。

我看到静态ThreadLocal每次会话创建时都会被删除。

但同样的项目正在与SDN 4.0.0和OGM 1.1.4版本正常工作。所以作为一个解决方案,我不得不作出Sessionthread作用域。任何人都可以澄清对SDN/OGM进行了哪些修改可能导致这种情况。或者这是SDN 4.1.X中的预期行为?

+0

您正在从OGM 1.x升级到2.x.那里有很多重大变化。 OGM 2.0.x允许使用'线程'范围会话,但是我的建议是不使用它。你试图达到什么目标,需要在应用程序的整个生命周期内保留所有数据库对象?如果您正在升级,我强烈建议迁移到SDN 4.2/OGM 2.1,因为这些版本中的变化比4.1/2.0更多。 – digx1

+0

我在答案部分提供了更多信息。请让我知道你的意见。 – Sourav

回答

0

感谢您的回复。

让我澄清一下应用范围。 我的应用程序是异步/并发和非阻塞性质的反应堆。

并发性由基于池的分组的反应器流API控制。 这意味着数据存储在Neo4J中,通过并发线程(工作人员) 多个组(线程池)根据特定的应用程序特定的分组上下文创建。 在一组内,与Neo4J的交互始终是顺序的。

因此,以下是我所考虑用于Neo4j的会话的选项,(I已经使用在配置@EnableTransactionManagement@Transactional在该方法与Neo4j的交互)

  1. "session" - 这不能被用作应用(主要是后端应用程序)不使用Spring-MVC容器
  2. "prototype" - 表示将为每个数据库命中初始化新会话对象。这适用于SDN 4.0.0和OGM 1.x. 但升级后的库不再适用。该会话是容器管理的,并且不在交易边界之外使用
  3. "thread" - 这需要显式注册范围。但是,会话在整个线程生命周期中保持活动状态。 这确实会扩大内存占用空间,应该重复清理/刷新以保持数据完整性。

我想升级到SDN 4.2.X,但唯一的SNAPSHOT可用,我有点怀疑继续。

此外,我看到,当交易方面(@EnableTransactionManagement)被删除,它工作正常。但我想知道,它是否正确处理交易。

有关Neo4J OGM中事务管理困惑的问题,其中会话无法在Singleton或Session范围中初始化?或者围绕这种情况的首选工作是什么?

+0

你可能应该把它移到问题本身,因为它不是一个答案。 – digx1

+0

另外正如我在我的回答中所提到的,你不应该再为它定义一个'Session'' @ Bean'或者一个相关的范围。所有你需要做的就是在任何Spring管理的'@ Component'或'@ Service'等中定义'@Autowired Session session'(只要确保在与会话交互时使用'@Transactional'或'TransactionTemplate'来利用Spring的交易管理)。当你这样做时,重要的是让注意到的'Session' bean实际被代理。如果它已经存在于事务的上下文中,它将使用相同的bean。 – digx1

0

好的我认为我理解了这些问题。

在SDN 4.2/OGM 2.1之前,配置和事务处理完全不同。用户需要在扩展为Neo4jConfiguration的配置类中定义并指定Session bean上的作用域。这导致开发人员在应用程序的使用范围方面出现了很多混乱。在这个最新版本中,这已经完全取消了。你可以看到如何升级this blog post。我们也不会支持这个旧的配置机制。

接近本月底的新版本SDN将为RC1,12月12日左右为RELEASE,因此它将不再是SNAPSHOT太久了!

博客文章还讨论了交易如何工作。

+0

好的。一旦GA可用,我宁愿计划再进行一次迁移。直到我不得不忍受SDN 4.1.3.RELEASE和OGM 2.0.5。那么你在每个工作单元之前使用“线程”范围和session.clear()是什么。 (@Traverseal中的代码)?这是我目前看到的唯一可用的工作。 – Sourav