Spring-Cloud、Hystrix 和 JPA - LazyInitializationException

Posted

技术标签:

【中文标题】Spring-Cloud、Hystrix 和 JPA - LazyInitializationException【英文标题】:Spring-Cloud, Hystrix and JPA - LazyInitializationException 【发布时间】:2015-05-31 04:09:16 【问题描述】:

我在尝试将 Hystrix 集成到现有的 Spring Boot 应用程序时遇到以下问题。我正在使用带有 spring 数据(jpa 存储库)的引导。该应用程序的结构非常简单, 我们有资源 -> 服务 -> 存储库。

我启用了 Hystrix 支持并注释了返回实体的服务方法之一,如下所示:

@HystrixCommand(fallback="getDealsFallback")
public Page<Deal> getDeals(...) 
  // Get the deals from the Index Server.
  return indexServerRepository.findDealsBy(...);


public Page<Deal> getDealsFallback(...) 
  // If IndexServer is down, query the DB.
  return dealsRepository.findDealsBy(...);

所以这按预期工作,真正的问题实际上在于我将实体返回给客户端时。我正在使用 OpenEntityManagerInViewFilter 所以我可以用它的关系序列化我的模型。 当我在我的服务方法中使用@HystrixCommand 时,当它尝试序列化时我得到一个 LazyInitializatioException。

我知道原因(或者至少我怀疑是什么问题),并且是因为 Hystrix 正在另一个线程中执行 所以不是交易的一部分。将 Hystrix 隔离策略从 THREAD 更改为 SEMAPHORE,因为它是同一个线程,所以可以正常工作,但我知道这不是解决问题的正确方法。

所以我的问题是,我怎样才能让 Hystrix 执行线程成为事务的一部分。有什么我可以申请的解决方法吗?

谢谢!

【问题讨论】:

by 将实体返回给客户端你是指jsp吗?还是在控制器中? 是一个 Rest API,所以回答你的问题,一个 JSP。 如果您需要线程上下文(这就是它的用途),我认为 SEMAPHORE 是您的最佳选择。 Hystrix 配置页面 (github.com/Netflix/Hystrix/wiki/Configuration) 指出“通常,您应该使用信号量隔离 (SEMAPHORE) 的唯一时间是当调用量如此之大(每秒数百次,每个实例)... “这让我很紧张使用这种策略只是为了让交易正常进行。其他人怎么看? 【参考方案1】:

这是一个有点旧的线程,但也许有人也遇到了这个问题。 github 中有一个issue 与此有关。

原因是,hystrix 会在单独的线程中运行,这与之前的事务所在的位置不同。所以惰性的事务和序列化将不起作用。

“线程”也是推荐的执行策略。所以如果你想同时使用 hystrix 和 transaction,你应该在 2 级调用中使用它们。比如,在一级服务函数中,使用事务,在二级服务函数中,使用hystrix,调用一级事务函数。

【讨论】:

以上是关于Spring-Cloud、Hystrix 和 JPA - LazyInitializationException的主要内容,如果未能解决你的问题,请参考以下文章

Spring-cloud Hystrix 请求缓存的使用

Spring-Cloud系列-Hystrix源码解析

Spring-Cloud系列-Hystrix源码解析

spring-cloud feign hystrix配置熔断为啥不生效的原因

Spring-cloud Hystrix入门

干货分享微服务spring-cloud(4.负载均衡ribbon与熔断器hystrix)