มันแย่แค่ไหนที่จะไม่กำจัด () SqlConnections


14

โดยส่วนตัวแล้วฉันแบ่งเป็นลมพิษถ้าฉันไม่ใส่วัตถุ ADO ที่ใช้ IDisposable ในการใช้คำสั่ง แต่ที่สัญญาปัจจุบันของฉันฉันพบว่ากรอบรหัสองค์กร "ผู้ให้บริการการเข้าถึงข้อมูล" ขององค์กรไม่ได้ใช้ 1) ใช้ IDisposable และ 2) เรียกใช้ Dis ทิ้ง () กับทุกสิ่งที่ใช้อยู่ทุกที่ทุกเวลา ผู้ใช้บ่นเกี่ยวกับปัญหาด้านประสิทธิภาพในแอปพลิเคชั่น Winforms ซึ่งใช้เฟรมเวิร์กนี้เพื่อการเข้าถึงข้อมูลเป็นอย่างมากและแม้ว่าจะมีปัญหาอื่น ๆ อีกมากมายในรหัสที่อาจส่งผลกระทบต่อประสิทธิภาพการทำงาน ผลไม้แขวนต่ำกว่าแบบอื่น

ดังนั้นนอกเหนือจากการพูดอะไรบางอย่างเช่น "ทิ้งมีไว้สำหรับเหตุผลให้ใช้มัน" ฉันจะบอกอะไรให้คนเหล่านี้โน้มน้าวใจพวกเขาว่านี่มันแย่จริง ๆ หรือ?


5
Heh..my เดาคือว่าในบางจุดที่น่าเชื่อจะไม่จำเป็น :)
ดรฮันนิบาลเล็คเตอร์

คำตอบ:


6

ผมว่าสิ่งที่ดีที่สุดที่คุณสามารถทำได้คือการชี้ให้พวกเขาไปยังรูปแบบไมโครซอฟท์และการปฏิบัติเกี่ยวกับที่นี่Dispose() ให้พวกเขาเห็นผลที่ตามมาอย่างเต็มที่จากการไม่ใช้เครื่องมือนี้ที่อยู่ตรงหน้าพวกเขา


1
แค่หวังว่าฉันจะหารุ่นที่ไม่ได้กรีดร้องว่า "นี่คือเนื้อหาที่เลิกใช้" ที่ด้านบน
AJ Johnson

คุณก็รู้ว่าดวงตาของฉันส่องแสงนั้น แต่ตอนนี้อ่านมันอย่างถี่ถ้วนฉันสงสัยว่าเทคโนโลยีใดที่ผู้คนอาจ "ยังคงใช้อยู่" ซึ่งเลิกใช้งานจากหน้านั้น บางที CAS?
Jesse C. Slicer

การสแกนอย่างใกล้ชิดยิ่งขึ้นส่วนใหญ่ยังคงเกี่ยวข้องกับฉัน ไม่แน่ใจว่าทำไมถึงมีการยกเลิก
AJ Johnson

10

ถ้าคุณไม่เรียกใช้เมธอด Dispose บนการเชื่อมต่อ SQL เมื่อคุณใช้งานเสร็จการเชื่อมต่อนั้นจะไม่ถูกส่งกลับไปยังพูลการเชื่อมต่อ

หากคุณกำลังมีปัญหาด้านประสิทธิภาพฉันเดาว่าการเชื่อมต่อสูงสุดจะเปิดขึ้นในฐานข้อมูลของคุณ DBA สามารถยืนยันสิ่งนี้ได้อย่างง่ายดาย

วิธีปฏิบัติที่ดีที่สุดของ Microsoft เรียกร้องให้คุณวางรหัสการเชื่อมต่อของคุณไว้ในคำสั่งการใช้เพื่อให้แน่ใจว่าการเชื่อมต่อนั้นถูกกำจัดและการเชื่อมต่อจะถูกส่งกลับไปยังพูล


การโทรCloseเพียงพอที่จะปล่อยกลับไปยังพูลการเชื่อมต่อ คำถามไม่ได้ระบุCloseว่าไม่ได้ใช้อย่างชัดเจน
2864740

9

พูลการเชื่อมต่อฐานข้อมูลมีขนาด จำกัด และถ้าเต็มแล้วการเชื่อมต่อใหม่จะรอการเชื่อมต่อเก่าที่จะนำออกใช้ ถ้าคุณไม่ทิ้งพวกเขาทันทีที่คุณทำเสร็จแล้วกับพวกเขาพวกเขาจะในที่สุดได้รับการปล่อยตัวเมื่อ finaliser วิ่ง แต่ที่จำนวนเงินที่ไม่แน่นอนของเวลาในอนาคต ... ดังนั้นที่ดีที่สุดที่คุณกำลังจะ ดูความล่าช้านานเมื่อเปิดการเชื่อมต่อใหม่

อย่างน้อยที่สุดพวกเขาอาจปิดใช้งานพูลการเชื่อมต่อ บางทีพวกเขาค้นพบว่าข้อผิดพลาดในขณะที่แอปของพวกเขากลับมา "หมดเวลารอการเชื่อมต่อ" และปิดการใช้งานกลุ่มการเชื่อมต่อ "แก้ไข" ปัญหานั้น อย่างไรก็ตามสิ่งนี้แย่กว่ามากเพราะนั่นหมายความว่าคุณกำลังสร้างการเชื่อมต่อใหม่ทั้งหมดทุกครั้ง - ซึ่งเป็นทรัพยากรที่น่าแปลกใจมาก หากคุณมีหลายร้อยการเชื่อมต่อกับฐานข้อมูลเปิดอยู่คงไม่น่าแปลกใจที่คุณเห็นปัญหาด้านประสิทธิภาพ

วิธีที่ถูกต้องในการแก้ไขปัญหาเหล่านี้คือการกำจัดการเชื่อมต่อของคุณทันทีที่คุณทำเสร็จ ความคิดที่ดีที่สุดคือให้การเชื่อมต่อเปิดค้างไว้นานเท่าที่ต้องการและไม่นาน


1
มันเลวร้ายยิ่งกว่านี้อีกเล็กน้อย หากพูลสำรองเพียงพอความพยายามในการเชื่อมต่อจำนวนมากก็จะล้มเหลวในที่สุดก็รวมถึงความพยายามในการเชื่อมต่อจากเครื่องมือการจัดการและคุณสามารถล็อคฐานข้อมูลของเราได้อย่างมีประสิทธิภาพ
Joel Coehoorn

3

ในแอปพลิเคชั่นที่จริงจัง ๆ ฉันจะบอกว่ามันแย่มาก ไม่เพียง แต่จะปล่อยให้วัตถุเหล่านี้ลอยไปรอบ ๆ ประสิทธิภาพการฆ่า แต่ยังไม่เป็นมืออาชีพ ข่าวดีก็คือว่า Microsoft ดำเนินการเสร็จสิ้นในลำดับชั้นของวัตถุ

~Object()
{
    this.Dispose(false);    
}

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    // ...
}

ใช้System.Data.SqlClient.SqlConnectionตัวอย่างเช่น:

System.ComponentModel.Component <- ใช้รูปแบบการกำจัดสุดท้าย
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

ในที่สุดวัตถุจะถูกกำจัด แต่ธรรมชาติที่ไม่ได้กำหนดไว้จะก่อให้เกิดความเสียหายต่อประสิทธิภาพการทำงาน


0

สำหรับหนึ่งคุณไม่ได้ยกเลิกการเชื่อมต่อ ดังนั้นจึงต้องมี a) ถูกดร็อปโดยอัตโนมัติหรือข) รับกรณืผ่านและอัปเดตแม้ว่าลูกค้าจะไม่ใช้มัน

ฉันจะถือว่าb)เนื่องจากการแสดงที่คุณกำลังอธิบาย อย่างไรก็ตามนั่นอาจไม่ใช่เหตุผลเดียว

คุณต้องปิดการเชื่อมต่อของคุณโดยเฉพาะอย่างยิ่งในฝั่งไคลเอ็นต์ แต่คุณต้องใช้ความล้มเหลวที่ปลอดภัยในฝั่งเซิร์ฟเวอร์ มิฉะนั้นคุณก็จะมีอึพิเศษซ้อนบนเซิร์ฟเวอร์ฐานข้อมูลของคุณจะต้องดำเนินการจนกว่ามันจะถูกปล่อยออกมาที่ god-Know-when

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.