สำหรับคำอธิบายอีกต่อไปคุณสามารถอ่านของฉันเปิด Session ในมุมมองต่อต้านรูปแบบบทความ มิฉะนั้นนี่คือสรุปสาเหตุที่คุณไม่ควรใช้ Open Session In View
Open Session In View ใช้วิธีการที่ไม่ดีในการดึงข้อมูล แทนที่จะปล่อยให้ชั้นธุรกิจตัดสินใจว่าจะดึงการเชื่อมโยงทั้งหมดที่ต้องการโดยเลเยอร์ View ได้อย่างไร แต่จะบังคับให้ Persistence Context ยังคงเปิดอยู่เพื่อให้เลเยอร์ View สามารถทริกเกอร์การเริ่มต้น Proxy ได้

OpenSessionInViewFilterเรียกopenSessionวิธีการพื้นฐานและได้รับใหม่SessionFactorySession
- ถูกผูกไว้กับ
SessionTransactionSynchronizationManager
- การ
OpenSessionInViewFilterเรียกใช้doFilterการjavax.servlet.FilterChainอ้างอิงอ็อบเจ็กต์และคำร้องขอจะถูกประมวลผลเพิ่มเติม
DispatcherServletเรียกว่าและเส้นทางการร้องขอ HTTP PostControllerเพื่อพื้นฐาน
PostControllerเรียกPostServiceที่จะได้รับรายชื่อของPostหน่วยงาน
PostServiceเปิดรายการใหม่และHibernateTransactionManagerreuses เดียวกันที่ถูกเปิดออกโดยSessionOpenSessionInViewFilter
PostDAOเรียกรายชื่อของPostหน่วยงานโดยไม่ต้องเริ่มต้นการเชื่อมโยงใด ๆ ขี้เกียจ
PostServiceกระทำธุรกรรมพื้นฐาน แต่Sessionไม่ได้ปิดเพราะมันถูกเปิดออกภายนอก
- การ
DispatcherServletเริ่มต้นการแสดงผล UI ซึ่งในทางกลับกันจะนำทางการเชื่อมโยงแบบ lazy และทริกเกอร์การเริ่มต้น
OpenSessionInViewFilterสามารถปิดSessionและเชื่อมต่อฐานข้อมูลพื้นฐานจะถูกปล่อยออกเช่นกัน
เมื่อมองแวบแรกสิ่งนี้อาจดูเหมือนไม่ใช่เรื่องน่ากลัวที่ต้องทำ แต่เมื่อคุณดูจากมุมมองของฐานข้อมูลข้อบกพร่องต่างๆจะเริ่มชัดเจนขึ้น
ชั้นบริการเปิดและปิดธุรกรรมฐานข้อมูล แต่หลังจากนั้นไม่มีธุรกรรมที่ชัดเจนเกิดขึ้น ด้วยเหตุนี้ทุกคำสั่งเพิ่มเติมที่ออกจากเฟสการเรนเดอร์ UI จะถูกดำเนินการในโหมดการคอมมิตอัตโนมัติ การคอมมิตอัตโนมัติจะสร้างแรงกดดันให้กับเซิร์ฟเวอร์ฐานข้อมูลเนื่องจากแต่ละคำสั่งต้องล้างบันทึกธุรกรรมลงในดิสก์ดังนั้นจึงทำให้มีการรับส่งข้อมูล I / O จำนวนมากที่ฝั่งฐานข้อมูล การเพิ่มประสิทธิภาพอย่างหนึ่งคือการทำเครื่องหมายConnectionว่าอ่านอย่างเดียวซึ่งจะช่วยให้เซิร์ฟเวอร์ฐานข้อมูลหลีกเลี่ยงการเขียนลงในบันทึกธุรกรรม
ไม่มีการแยกข้อกังวลอีกต่อไปเนื่องจากคำสั่งถูกสร้างขึ้นโดยชั้นบริการและโดยกระบวนการแสดงผล UI การเขียนการทดสอบการรวมที่ยืนยันจำนวนคำสั่งที่สร้างขึ้นจะต้องผ่านทุกเลเยอร์ (เว็บบริการ DAO) ในขณะที่มีการปรับใช้แอปพลิเคชันบนเว็บคอนเทนเนอร์ แม้ว่าจะใช้ฐานข้อมูลในหน่วยความจำ (เช่น HSQLDB) และเว็บเซิร์ฟเวอร์ที่มีน้ำหนักเบา (เช่น Jetty) การทดสอบการรวมเหล่านี้จะดำเนินการได้ช้ากว่าการแยกชั้นและการทดสอบการรวมส่วนหลังจะใช้ฐานข้อมูลในขณะที่ การทดสอบการรวมส่วนหน้ากำลังจำลองชั้นบริการโดยสิ้นเชิง
เลเยอร์ UI จำกัด เฉพาะการนำทางที่เชื่อมโยงซึ่งสามารถทำให้เกิดปัญหาการสืบค้น N + 1 ได้ในทางกลับกัน แม้ว่าไฮเบอร์เนตจะเสนอ@BatchSizeการดึงการเชื่อมโยงเป็นกลุ่มและFetchMode.SUBSELECTเพื่อรับมือกับสถานการณ์นี้ แต่คำอธิบายประกอบจะส่งผลต่อแผนการดึงข้อมูลเริ่มต้นดังนั้นจึงนำไปใช้กับทุกกรณีการใช้งานทางธุรกิจ ด้วยเหตุนี้แบบสอบถามชั้นการเข้าถึงข้อมูลจึงเหมาะสมกว่ามากเนื่องจากสามารถปรับแต่งให้เหมาะกับข้อกำหนดการดึงข้อมูลกรณีการใช้งานปัจจุบัน
สุดท้าย แต่ไม่ท้ายสุดการเชื่อมต่อฐานข้อมูลอาจถูกระงับตลอดระยะการแสดงผล UI (ขึ้นอยู่กับโหมดการปล่อยการเชื่อมต่อของคุณ) ซึ่งจะเพิ่มเวลาเช่าการเชื่อมต่อและ จำกัด ปริมาณงานธุรกรรมโดยรวมเนื่องจากความแออัดในพูลการเชื่อมต่อฐานข้อมูล ยิ่งมีการเชื่อมต่อมากขึ้นคำขออื่น ๆ ที่พร้อมกันจะต้องรอรับการเชื่อมต่อจากพูลมากขึ้น
ดังนั้นไม่ว่าคุณจะถูกระงับการเชื่อมต่อไว้นานเกินไปหรือคุณได้รับ / ปล่อยการเชื่อมต่อหลายรายการสำหรับคำขอ HTTP เดียวดังนั้นจึงกดดันพูลการเชื่อมต่อที่อยู่เบื้องหลังและ จำกัด ความสามารถในการปรับขยาย
สปริงบูต
แต่น่าเสียดายที่เปิดเซสชันในวิวถูกเปิดใช้งานโดยเริ่มต้นในฤดูใบไม้ผลิ Boot
ดังนั้นตรวจสอบให้แน่ใจว่าในapplication.propertiesไฟล์กำหนดค่าคุณมีรายการต่อไปนี้:
spring.jpa.open-in-view=false
นี้จะปิดการใช้งาน OSIV เพื่อให้คุณสามารถจัดการกับLazyInitializationExceptionวิธีการที่เหมาะสม