[软件] 卧龙会:【软件】Hibernate session开启与数据库物理连接的时间关系

[复制链接]

技术员

发表于 2018-1-22 17:10:47   381 查看 0 回复 显示全部楼层 倒序浏览
分享
点击右上角“卧龙会IT技术”关注我们
我们与你一起畅享IT世界!


文|原创:卧龙会   Arivn


先说结论:

[size=1em]spring openSession获取到的是hibernate session,并没有实际获取绑定数据库连接。
不到最后一刻,不操作db就不会获取实际的数据库连接。当第一次操作db时,hibernate session 才会绑定数据库物理连接。这样降低了session使用数据库连接时间片段,最大化的利用链接资源。


所以spring连接打开的session是hibernate Session,原创微信公众号:卧龙会IT技术。并不是实际数据库连接,可放心使用(提前Open hibernate Session 对数据库链接无消耗,所以spring filter才能帮助用户提前打卡session)

注:以下是基于hibernate和spring集成的前提下进行的。

一般spring的事物是配置在service上,所以来说service和controller上的情况

1 service 层情况

绑定数据库物理连接是在第一次操作数据库的时候发生。操作数据库包括查询,修改,删除,新增,当然还有事物。在service中后续的db操作继续使用第一次绑定的数据库连接,直到service方法退出结束。

  • 对于非事物的查询(PROPAGATION_SUPPORTS)
    不管你在service查询前做了什么复杂的业务,都不会绑定数据库链接
    如下代码:

@Override public UserInfo getById(long id) {      log.info("操作前sleep 10s,模拟调用外部接口");      this.sleep(10);      log.info("执行操作");      //以上时间段查看链接池,数据库链接未被消耗      UserInfo bean= baseDAO.get(UserInfo.class, id);//链接开始被消耗      //以下时间段,由于未退出方法,不会触发spring自动释放链接      //会一直暂用数据库链接      log.info("操作后sleep 10s");      this.sleep(10);      log.info("方法结束");      return bean;//退出后释放链接  }


  • 对于事物。开启事物时打开链接(PROPAGATION_REQUIRED)
    进入方法就绑定了数据库链接,所以事物里面的逻辑单元应该精简,不要有太多和事物无关的逻辑。比如提交一个http请求,在请求中会浪费掉数据库链接的时间

  @Override    public void saveTest(long id) throws BizException {        //进入方法就绑定了数据库链接        this.sleep(10);        long sn=System.currentTimeMillis();;        baseDAO.executeHql("UPDATE UserInfoEx set address=? where id =?"        ,new Object[]{sn+"",id});//已经处理完了        log.info("延迟10秒,"+sn);        this.sleep(10);//模拟远程调用反馈执行结果        log.info("提交"+sn);        //退出后释放链接    }


  • service方法中调用内部其他方法
    只会绑定一次数据库连接,第二次操作DB使用的是第一次操作DB绑定的链接,同样会把事物特性传递下来。

    @Overridepublic UserInfo getById(long id) {    //第一次操作绑定数据库链接    UserInfo bean= baseDAO.get(UserInfo.class, id);    updateName(id,bean.getName()+System.currentTimeMillis());    // 不会重新绑定链接,继续使用baseDAO.get(UserInfo.class, id)绑定的链接。    baseDAO.save(bean);    //也不会触发真实的保存,因为没有经过代理拦截,(在自己本身调用本身的方法,即原始目标方法),不会触发事物开启。    this.saveOptLog(id);    return bean;}

    [size=1em]注意:上面的代码 baseDAO.save(bean)和 this.saveOptLog(id)并不会触发真实的保存和提交。事物和自动提交是加在service层,getById不会触发事物的开启和自动提交。如果saveOptLog是其他servcie中注入的方法会自动开启的事物,但是继续使用同一连接,如下代码:

    @Overridepublic UserInfo getById(long id) {    //第一次操作绑定数据库链接    UserInfo bean= baseDAO.get(UserInfo.class, id);    updateName(id,bean.getName()+System.currentTimeMillis());     baseDAO.save(bean);    //1 不会重新绑定链接,logService中从线程变量中获取session,而session中已经由baseDAO.get绑定过物物理连接    //2 会触发真实的保存,因为注入的logService,是代理对象有spring增强,会自动开启事物和提交    logService.saveOptLog(id);    return bean;}   
  • 2 controller 情况

  • 每调用一次service都会绑定一个数据库物理连接,并且执行完后释放掉。
    原因:service是spring注入进来的代理service,有事物增强处理。

    @RequestMapping("/loginLog")@ResponseBodypublic JsonResponseBean loginLog(@RequestScope JSONObject jsonParams) throws BizException {    JsonResponseBean responseBean = new JsonResponseBean();    UserInfo userInfo=userService.getById (jsonParams.getLongValue("id"));//绑定数据连接,执行,并释放    this.sleep(10);//模拟复杂的控制处理,此处不会消耗数据连接资源的时间片。    loginService.saveLoginLog(UserLoginLog.TYPE_PASSWORD, userInfo.getId(), userInfo.getName(), "","","","");//第一次调用,重新绑定连接,执行,释放连接    loginService.saveLoginLog(UserLoginLog.TYPE_PASSWORD, userInfo.getId(), userInfo.getName(), "","","","");//重复调用,重新绑定连接,执行,释放连接    return responseBean;}
  • 如果是处理重复业务数据,preparestatement不一定会生效。
    原因:controller重复调用service的方法绑定到的数据库连接不一定是同一个,preparestatement是基于同一连接生效的。如果preparestatement要生效需要放在service内处理。

    //controller代码public JsonResponseBean loginLog(@RequestScope JSONObject jsonParams) throws BizException {    JsonResponseBean responseBean = new JsonResponseBean();    List<Long> ids=JsonUtils.toArray(jsonParams.getJSONArray("id"),Long.class);    for(long id:ids) {        UserInfo userInfo = userService.getById(id);        loginService.saveLoginLog(UserLoginLog.TYPE_PASSWORD, userInfo.getId(), userInfo.getName(), "", "", "", "");//每次都是,重新绑定连接,执行,释放连接。    }    return responseBean;}

3 控制代码划分规则建议
一般来说service根据模块功能和解耦,里面可能会包含部分的业务逻辑控制代码;controller本身是控制层,也会包含部分逻辑控制代码。那么逻辑控制代码怎么区分是方在service层还是controller呢?

如果是处理比较复杂的业务请求,并且可能消耗的时间比较久(正常情况应该走MQ进行异步处理,但这个地方讨论不能走异步必须面对的情况)。需要把消耗时间的业务逻辑控制上浮,放在controller中处理,即使是同一service。



erivce和controller的规则:

  • 1 根据模块功能划分,并进行解耦
    当仁不让,第一规则,优先考虑。

  • 2 serivce层的逻辑粒度尽量小,尽量单一
    保持service方法的逻辑简洁性,往往一个方法处理逻辑过多会很容易造成代码混乱,并且不容易维护。

  • 3 在小粒度的方法前提下,控制业务逻辑进行上浮
    如果是非事物,可以考虑吧逻辑代码上浮到controller,由controller进行组合调用service接口。
    如果是事物业务,必须把代码逻辑放在service层,但也需要保持每个方法的小粒度,再由一个方法来进行业务逻辑层控制,并暴露给contrller使用。
    当然非业务的事物情况下,也可以把部分contrller里面共同的逻辑,下潜到service实现。(具体根据service具体业务属性进行划分)
    但同上,每个子方法都应该具有小粒度和单一的特性。

    为什么要这样做?在上面提到,当第一次操作db后,如果方法一直没执行完并退出,会一直占用链接。这段时间链接是无法被其他人使用的,哪怕链接处于空闲状态。

    这样的结果就是100个复杂的业务来了,service层使用了100个数据链进行长时间处理(连接池只提供100个链接),这时其他一个执行查询的小业务请求来了,由于链接全部被占用了,这时这地101个请求就无法处理,只有等。

    如果service足够简单,让controller来控制部分业务逻辑(由一个一个小粒度的service方法组成),
    A 调用一个service方法结束后会先把链接释放出来;
    B 这时其他业务请求才有可能获取到链接,并进行处理,小请求处理完后会释放链接;(能很快的做出相应)
    C 之前的contrller继续调用serivce方法,绑定到释放的链接,继续处理。(响应速度延迟不大)
    这样100个链接能支持100个以上的请求业务,才能【实现高并发】。否则100个链接提供的并发支持非常有限。


    关键思路:
  • 1 调用小粒度service方法,让使用完后,及时释放,尽量避免不用但一直占用资源的时间段产生
    2 让使用db资源的时间片尽可能的小,处理过程中可以让其他需要资源的业务请求也能够参与进来 。原创微信公众号:卧龙会IT技术。
    3 让想用资源的能及时用到资源,占用资源但空闲状态的释放资源,【最大化】利用有限的资源。

以上是大多数情况下的处理方式,但不能一篇而论。需要根据功能模块和业务场景选择性的使用。

---好东西就要分享给你朋友圈---


想知道近来IT行业工资标准,关注微信公众号:卧龙会IT技术

给公从号回复“薪资调查”,我们把IT行业薪资调查报告发给你。

大家喜欢用微博的,关注我们微博
卧龙会微博:@卧龙会IT技术
我们同步更新到微博!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
标签:软件 hibernate 数据库

只有小组成员才能发言,加入小组>>

26个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /9 下一条

快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

方案交易

用户帮助┃咨询与建议┃版主议事

工程师杂谈

工程师创意

招聘|求职}工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

MSP430技术论坛

FPGA|CPLD|ASIC论坛

STM32/STM8技术论坛

NXP MCU 技术论坛

PIC单片机论坛

DSP论坛

瑞萨单片机论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

工程资源中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

电子展览展会专区

芯片求购|供应发布区