小心 spring.jpa.open-in-view 導致 DB connection 被拿光

 spring.jpa.open-in-view

  • spring boot 的 property, spring.jpa.open-in-view 預設是開啟的
  • 開啟的話, OpenSessionInViewInterceptor 就會介入
    • 收到 web request 的時候, 會開一個 Hibernate Session
    • 如果用到 DB, 就會拿一個 DB Connection
    • 完成 request, 就把 connection 關閉


目的
  • 原本一個 entity 有像是 OneToMany 的關聯時, 預設都會 lazy.
  • 需要特別啟用這個 collection, 就需要特別去初始化, 例如 Hibernate.initialize
  • 如果沒有初始化就會遇到 LazyInitializationException


問題
  • 如果處理一個 request 的時候會需要比較長的時間, 那 DB connection 就會被卡住
  • BTW, 預設 DB connection 是 10條 ( https://github.com/brettwooldridge/HikariCP )
  • 如果需要呼叫外部服務, 或是外部服務遇到 connection timeout 之類的問題, 會導致一個 request 花很多時間才結束
  • 而導致 connection 很快被拿光, 而且無法拿到新的 connection 而爆炸..


怎麼辦?
disable open-in-view
  • spring.jpa.open-in-view, 把這個設成 false, 可以避免 connection 跟著 request
  • 可是要注意如果有 lazy 的地方要 initialize 否則會遇到 lazy exception
限制 request 的時間
  • 把時間可能拉長的設計跟 DB access 分開來
  • 例如把對外部系統的呼叫分開來

Reference
可能會需要調整 HikariCP 的 pool size, 參考: https://github.com/brettwooldridge/HikariCP

沒有留言:

張貼留言

別名演算法 Alias Method

 題目 每個伺服器支援不同的 TPM (transaction per minute) 當 request 來的時候, 系統需要馬上根據 TPM 的能力隨機找到一個適合的 server. 雖然稱為 "隨機", 但還是需要有 TPM 作為權重. 解法 別名演算法...