当前位置: 首页 > 知识库问答 >
问题:

Java带Spring注释的方法

卢和昶
2023-03-14

我尝试在DAO中使用带有Spring@Transactional注释的并行流(),但遇到了这样的问题:

@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)

如何使用parallelStream()注释的事务方法?

更新为什么会发生这种情况Spring事务管理器和多线程,但我希望支持java 8的Spring 4能够提供一些解决方案。有什么想法吗?

共有2个答案

华升
2023-03-14

问题不在于并行流。spring中的事务是使用AOP创建的
当执行processCollection方法时,spring会创建该方法的代理对象,然后启动事务。调用同一类中的另一个方法,即使您指定了@transaction,spring也不会在新事务中运行该方法。要使其运行,请将该方法process()移动到新服务,然后执行您的问题。您的程序将正常运行。

阴鸿才
2023-03-14

嗯,我有一个猜测包括几个猜测:

  • 您的会话管理策略为每线程会话
  • 您在示例中编写的对象实际上是某个使用延迟加载的实体;
  • Process One()方法使用延迟加载的实体属性;
  • 因为第一点,为并行流()启动的线程没有可用的会话(可能在线程本地中,不记得会话在技术上是如何绑定到线程的);

这就造成了你的问题。这种行为在我看来很奇怪,因此我建议采取以下措施:

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

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

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

 类似资料:
  • 问题内容: 我很好奇弹簧注入如何处理带有注释的调用方法。如果我在方法上添加注释并返回实例,则我理解这告诉spring通过调用方法并获取返回的实例来创建bean。但是,有时必须使用该bean来连接其他bean或设置其他代码。完成此操作的通常方法是调用带注释的方法以获取实例。我的问题是,为什么这不会导致有多个bean实例漂浮? 例如,请参见下面的代码(取自另一个问题)。该方法带有注释,因此我可以想象s

  • 我正在使用注释处理器来处理方法参数的注释。 用于参数的注释类型有一个注释@参数 现在,当注释处理器运行时,我想检查参数注释()是否有参数注释。我通过执行以下代码来实现这一点。 由于某种原因,arg始终为空。是否有注释未返回的原因?

  • 问题内容: 我需要 在类中使用@X注释的方法或使用@X注释的方法的切入点 。我还 需要注释对象 。如果同时注释了类和方法,则 我更喜欢将方法注释作为参数 。 我尝试了以下操作,这将创建“不一致的绑定”警告。(为什么不将它们设置为null?) 下面创建“跨’||’的参数x的模糊绑定 在切入点”警告。(我认为这并不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将先前的尝试自然地分

  • 问题内容: 美好的一天。如下代码: 据我了解,如果方法中存在异常,则不会回滚事务。以及如何使它滚动?并返回SomeResult 问题答案: 您不应该以编程方式调用回滚。根据docs的建议,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。 在你的情况下,像这样 看一下@Transaction API 和有关回滚事务的文档。 如果尽管有文档建议,但仍要进行程序化回滚,则需要按照已建议的

  • 我有一个可用于注释的方面: 连接点: 我可以在具有

  • 我正在测试一个Spring重试,但似乎没有调用恢复。试图让它工作,但似乎详尽无遗。我传递给@recover no argument,Throwable,exception。改变了重试依赖的版本,似乎它包含在spring boot的aop中,并删除了它。Creading Geting Recovery没有被调用,出现以下异常Messege。 请求处理失败;嵌套异常是org.springframewo