gpt4 book ai didi

带有 spring 注释方法的 Java .parallelStream()

转载 作者:IT老高 更新时间:2023-10-28 13:57:45 26 4
gpt4 key购买 nike

我尝试在带有 Spring @Transactional 注释的 DAO 中使用 parallelStream() 并遇到问题:

@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) {
...
}

异常(exception):

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)

如何使用 parallelStream() 中的 @Transactional 注释方法?

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

最佳答案

嗯,我的猜测由几个猜测组成:

  • 您的 session 管理策略为 session-per-thread ;
  • Object您在示例中编写的实际上是一些使用延迟加载的实体;
  • processOne()方法使用延迟加载的实体属性;
  • 由于第一点,线程开始于 parallelStream()没有可用的 session (可能在 ThreadLocal 中,不记得从技术上讲 session 是如何绑定(bind)到线程的);

这完全导致了您遇到的问题。这种行为对我来说看起来很奇怪,所以我建议执行以下操作:

  • 删除所有延迟加载并尝试parallelStream()再次;
  • 如果成功,您必须在执行 parallelStream() 之前完全加载实体.

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

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

关于带有 spring 注释方法的 Java .parallelStream(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23266866/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com