Vla*_*adS 13 java spring multithreading java-8 java-stream
我尝试使用parallelStream()带有Spring @Transactional注释的DAO 并得到这样的问题:
@Transactional
public void processCollection(Collection<Object> objects) {
objects.parallelStream()
.forEach(this::processOne); //throw exception
}
@Transactional
public void processOne(Object o) {
...
}
Run Code Online (Sandbox Code Playgroud)
工作正确:
@Transactional
public void processCollection(Collection<Object> objects) {
objects.stream()
.forEach(this::processOne); //work correctly
}
@Transactional
public void processOne(Object o) {
...
}
Run Code Online (Sandbox Code Playgroud)
例外:
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)
Run Code Online (Sandbox Code Playgroud)
我如何使用带@Transactional注释的方法parallelStream()?
更新 为什么会发生这种情况Spring事务管理器和多线程 但是我希望Spring 4支持java 8可以为此提供一些解决方案.有任何想法吗?
好吧,我有一个猜测包括几个猜测:
session-per-thread;Object 你在例子中写的实际上是一些使用延迟加载的实体;processOne() 方法使用懒惰加载的实体属性;parallelStream()没有可用的会话(可能在ThreadLocal,不记得技术上会话如何绑定到线程);这完全导致了你的问题.这个行为对我来说很奇怪,所以我建议你做以下事情:
parallelStream();parallelStream().另一种方法:在执行之前从会话中分离所有列表元素parallelStream().
虽然Marko在评论中写道,但Session它不是线程安全的,所以这意味着你必须Session通过删除延迟加载或从会话中分离所有实体来消除使用.
小智 6
问题不在于并行流。在Spring中,事务是使用AOP创建的。
当执行 processCollection 方法时,spring 创建一个代理对象并启动事务。在同一个类中调用另一个方法,即使您指定了 @Transaction ,spring也不会在新事务中运行该方法。要让它运行,请将该方法 process() 移至新服务,然后执行您的问题。你的程序会正常工作。
| 归档时间: |
|
| 查看次数: |
6139 次 |
| 最近记录: |