本文介绍了带有spring注释方法的Java .parallelStream()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在DAO中使用 parallelStream()使用Spring @Transactional 注释并解决问题:

I try using the parallelStream() in DAO with Spring @Transactional annotations and get so problem:

@Transactional
public void processCollection(Collection<Object> objects) {
    objects.parallelStream()
            .forEach(this::processOne);  //throw exception
}

@Transactional
public void processOne(Object o) {
    ...
}

工作正确:

@Transactional
public void processCollection(Collection<Object> objects) {
    objects.stream()
            .forEach(this::processOne);  //work correctly
}

@Transactional
public void processOne(Object o) {
    ...
}

例外:

org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:978)

我如何使用 @Transactional 注释方法由 parallelStream()

How can I use @Transactional annotated methods by parallelStream()?

更新
为什么会发生这种情况
但我希望Spring 4支持java 8可以为此提供一些解决方案。有什么想法吗?

UpdateWhy this happen Spring transaction manager and multithreadingBut I hope spring 4 with java 8 support can provide some solution for this. Any ideas?

推荐答案

好吧,我猜了几个猜测:

Well, I have a guess consists of several guesses:


  • 您的会话管理策略为每线程会话;

  • <$ c您在示例中写的$ c> Object 实际上是一些使用延迟加载的实体;

  • processOne()方法使用懒惰加载的实体属性;

  • 由于第一点,为 parallelStream()启动的线程没有会话可用(可能在 ThreadLocal 中,不记得技术上会话如何绑定到线程);

  • You have session management policy as session-per-thread;
  • Object you wrote in example is in fact some entity that uses lazy loading;
  • processOne() method uses entity properties that are loaded lazily;
  • Because of first point, threads, started for parallelStream() has no session available (probably in ThreadLocal, don't remember how technically sessions are bound to threads);

这完全导致了你的问题。这个行为对我来说很奇怪,所以我建议你做以下事情:

That altogether causing the problem you have. The behavior looks quite strange to me, so I suggest to do the following:


  • 删除所有延迟加载并尝试 parallelStream()再次;

  • 如果成功,则必须在执行 parallelStream()

  • Remove all lazy loading and try parallelStream() again;
  • If that succeeds, you'll have to load the entities completely before performing parallelStream().

另一种方法:在执行 parallelStream()之前从会话中分离所有列表元素

虽然Marko在评论中写道, Session 不是线程安全的,这意味着你必须通过删除延迟加载或从会话中分离所有实体来摆脱 Session 的使用。

Although as Marko wrote in comments, Session is not thread-safe, so that means you have to get rid of Session usage either by removing lazy loading, or by detaching all entities from session.

这篇关于带有spring注释方法的Java .parallelStream()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-14 14:15