當前位置:
首頁 > 最新 > 卧龍會:軟體Hibernate session開啟與資料庫物理連接的時間關係

卧龍會:軟體Hibernate session開啟與資料庫物理連接的時間關係

文|原創:卧龍會 Arivn

先說結論:

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查詢前做了什麼複雜的業務,都不會綁定資料庫鏈接

如下代碼:

對於事物。開啟事物時打開鏈接(PROPAGATION_REQUIRED)

進入方法就綁定了資料庫鏈接,所以事物裡面的邏輯單元應該精簡,不要有太多和事物無關的邏輯。比如提交一個http請求,在請求中會浪費掉資料庫鏈接的時間

service方法中調用內部其他方法

只會綁定一次資料庫連接,第二次操作DB使用的是第一次操作DB綁定的鏈接,同樣會把事物特性傳遞下來。

注意:上面的代碼 baseDAO.save(bean)和 this.saveOptLog(id)並不會觸發真實的保存和提交。事物和自動提交是加在service層,getById不會觸發事物的開啟和自動提交。如果saveOptLog是其他servcie中注入的方法會自動開啟的事物,但是繼續使用同一連接,如下代碼:

2

controller 情況

每調用一次service都會綁定一個資料庫物理連接,並且執行完後釋放掉。

原因:service是spring注入進來的代理service,有事物增強處理。

如果是處理重複業務數據,preparestatement不一定會生效。

原因:controller重複調用service的方法綁定到的資料庫連接不一定是同一個,preparestatement是基於同一連接生效的。如果preparestatement要生效需要放在service內處理。

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技術 的精彩文章:

TAG:卧龍會IT技術 |