dede古风类网站源码,青岛seo网站排名,免费qq注册入口,天津谁做网站原理 open-in-view 是 Spring Boot ⾃动加载 Spring Data JPA 提供的⼀个配置#xff0c;全称为 spring.jpa.open-in-viewtrue#xff0c;它只有 true 和 false 两个值#xff0c;默认是 true。 这个配置为true时#xff0c;会导致Web MVC请求处理的一开始全称为 spring.jpa.open-in-viewtrue它只有 true 和 false 两个值默认是 true。 这个配置为true时会导致Web MVC请求处理的一开始就从连接池取一个数据库连接放到本地线程变量Web MVC请求处理结束后才会归还给连接池。 open-in-view 机制是为了解决在 mvc 的 controller 中使用了 hibernate 的 lazy load 的属性时 no session 抛出的LazyInitializationException 异常 这个处理逻辑位于OpenEntityManagerInViewInterceptor.preHandle在Sentinel处理代码SentinelResourceAspectExt之前所以Sentinel限流无法阻止JPA取数据库连接。
隐患一 如果业务代码中有耗时操作就导致数据库连接还回连接池变慢进而引起雪崩效应导致tomcat处理线程大量增加而处理性能却无法提高所有Web MVC请求都无法响应应用提供的服务中断。
ResponseBody
RequestMapping(value /xxx/send, method RequestMethod.POST)
SentinelResource(value xxxdcc#send, entryType EntryType.IN)
public SendXXXResp sendSms(RequestBody SendXXXVo sendXXXVo) {//同步调用第三方系统耗时超过一定时间如3sSendXXXResp sendXXXResp new SendXXXResp();return sendXXXResp;
} 如果数据库连接池最大连接数为200同步调用第三方系统耗时3s。那么这个接口的QPS达到70时会导致应用雪崩整个应用无法提供服务。
隐患二 当jpa与mybatis等框架混合使用时存在死锁的问题。一个Web MVC请求处理时JPA框架会从连接池中取一个数据库连接放入本地线程变量业务处理代码使用mybatis访问数据库也需要取一个数据库连接在极端情况下取不到就会等待导致JPA取的连接也没有还给连接池导致死锁。也会导致tomcat处理线程大量增加而处理性能却无法提高所有Web MVC请求都无法响应应用提供的服务中断。 示例代码
ResponseBody
RequestMapping(value /xxx/send, method RequestMethod.POST)
SentinelResource(value xxx#send, entryType EntryType.IN)
public SendXXXResp sendSms(RequestBody SendSmsVo sendSmsVo) {//使用mybatis框架访问数据库CallingConfig callingConfigcallingConfigMapper.selectById(sendXXXVo.getXXXAccount());SendXXResp sendXXXResp new SendXXXResp();return sendXXXResp;
} 如果数据库连接池最大连接数为200这个接口QPS达到200。即使方法体中没有耗时操作也会导致应用雪崩整个应用无法提供服务。 修改建议
将spring.jpa.open-in-view配置为false注意不要设置成了“spring.shardingsphere.jpa.open-in-view”不要使用JPA 的关联查询如不要使用OneToMany等关联查询的注解。以免open-in-view为false时出现LazyInitializationException 异常。
annel_account_config账号表与calling_config主叫号码表是一对多的关系
JPA中设置的关联查询
OneToMany(cascade CascadeType.ALL)
JoinColumn(name channelAccountId)
private ListCallingConfigInfo callingConfigList new ArrayList();
在Controller中进行了查询使用
ChannelAccountConfigInfo channelAccountConfigInfo channelAccountConfigRepository.findOne(1L);
ListCallingConfigInfo callingConfigList ObjectUtil.getOptional(()-channelAccountConfigInfo.getCallingConfigList()).orElse(new ArrayList());
for(CallingConfigInfo callingConfigInfo:callingConfigList){log.info(Calling:callingConfigInfo.getCalling());
}