Nó tệ đến mức nào khi không vứt bỏ () SqlConnections?


14

Cá nhân, tôi sẽ nổi giận nếu tôi không đặt các đối tượng ADO triển khai IDis Dùng trong các câu lệnh. Nhưng tại hợp đồng hiện tại của tôi, tôi đã thấy rằng mã "nhà cung cấp truy cập dữ liệu" trong khuôn khổ doanh nghiệp của họ không 1) triển khai IDis Dùng một lần và 2) gọi Dispose () trên bất kỳ thứ gì họ sử dụng, tại bất kỳ thời điểm nào. Người dùng đã phàn nàn rất nhiều về các vấn đề về hiệu năng trong các ứng dụng Winforms sử dụng rất nhiều khung này để truy cập dữ liệu, và mặc dù có rất nhiều vấn đề khác trong mã có thể ảnh hưởng đến hiệu năng, nhưng điều này chỉ làm tôi thất vọng và hơn thế nữa quả treo thấp hơn những quả khác.

Vì vậy, ngoài việc nói điều gì đó như "Vứt bỏ là có lý do, hãy sử dụng nó", tôi có thể nói gì với những người này để thuyết phục họ rằng điều này thực sự, thực sự tồi tệ?


5
Heh..tôi đoán là, tại một số điểm, việc thuyết phục sẽ không cần thiết :)
dr Hannibal Lecter

Câu trả lời:


6

Tôi muốn nói điều tốt nhất bạn có thể làm là hướng chúng đến các Mô hình và Thực tiễn của Microsoft Dispose() tại đây . Hãy cho họ thấy hậu quả đầy đủ của việc không sử dụng công cụ này ngay trước mắt họ.


1
Chỉ ước tôi có thể tìm thấy một phiên bản không hét lên "đây là nội dung đã nghỉ hưu" ở đầu.
AJ Johnson

Bạn biết đấy, đôi mắt của tôi chỉ lướt qua điều đó. Nhưng bây giờ đọc nó một cách cẩn thận, tôi tự hỏi những công nghệ mà mọi người có thể "vẫn đang sử dụng" đã rút khỏi trang đó. Có lẽ CAS?
Jesse C. Choper

Quét nó kỹ hơn, hầu hết điều này vẫn có vẻ phù hợp với tôi. Không chắc chắn tại sao nó được đánh dấu đã nghỉ hưu.
AJ Johnson

10

Nếu bạn không gọi phương thức Vứt bỏ trên Kết nối SQL, khi bạn sử dụng xong, kết nối đó KHÔNG được đưa trở lại nhóm kết nối.

Nếu bạn gặp vấn đề về hiệu năng, tôi đoán là các kết nối tối đa được mở trên cơ sở dữ liệu của bạn. Một DBA có thể dễ dàng xác nhận điều này.

Thực hành tốt nhất của Microsoft yêu cầu bạn đặt mã kết nối của mình bên trong câu lệnh Sử dụng, đảm bảo kết nối được xử lý và kết nối được đưa trở lại nhóm.


Gọi Closelà đủ để phát hành trở lại nhóm kết nối. Câu hỏi không nêu rõ Closelà không được sử dụng rõ ràng .
dùng2864740

9

Nhóm kết nối cơ sở dữ liệu bị giới hạn về kích thước và nếu nó lấp đầy, các kết nối mới sẽ chờ kết nối cũ được phát hành. Nếu bạn không loại bỏ chúng ngay khi bạn kết thúc với chúng, cuối cùng chúng sẽ được giải phóng khi trình hoàn thiện chạy, nhưng đó là một lượng thời gian không xác định trong tương lai ... Vì vậy, tốt nhất, bạn sẽ thấy sự chậm trễ lâu khi mở kết nối mới.

Tệ nhất, họ có thể đã vô hiệu hóa nhóm kết nối. Có lẽ họ đã phát hiện ra rằng sau một thời gian, ứng dụng của họ đã trả về lỗi "hết thời gian chờ kết nối" và vô hiệu hóa nhóm kết nối đã "giải quyết" vấn đề đó. Tuy nhiên, điều này tồi tệ hơn nhiều bởi vì điều đó có nghĩa là bạn đang tạo ra một kết nối hoàn toàn mới mỗi lần - điều này gây ngạc nhiên về tài nguyên. Nếu bạn có hàng trăm kết nối đến cơ sở dữ liệu mở, sẽ không có gì lạ khi bạn gặp vấn đề về hiệu suất.

Cách chính xác để giải quyết tất cả những vấn đề này là loại bỏ kết nối của bạn ngay khi bạn kết thúc với nó. Ý tưởng tốt nhất là giữ kết nối mở chính xác miễn là cần, và không còn nữa.


1
Thậm chí còn tệ hơn thế này một chút. Nếu nhóm được sao lưu đủ, nhiều nỗ lực kết nối cuối cùng sẽ thất bại, bao gồm cả các nỗ lực kết nối từ các công cụ quản lý và bạn có thể tự khóa cơ sở dữ liệu của chúng tôi một cách hiệu quả.
Joel Coehoorn

3

Trong bất kỳ ứng dụng nghiêm túc nào tôi sẽ nói rằng nó khá tệ. Không chỉ khiến những vật thể này trôi nổi xung quanh hiệu suất tiêu diệt, nó còn đơn giản là không chuyên nghiệp. Tin tốt là Microsoft triển khai Hoàn thiện trong hệ thống phân cấp đối tượng.

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

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

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

Lấy System.Data.SqlClient.SqlConnectionví dụ:

System.ComponentModel.Component <- Triển khai mẫu xử lý Hoàn thiện.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

Các đối tượng cuối cùng sẽ được xử lý nhưng bản chất không xác định sẽ làm hỏng hiệu suất.


0

Chà, trước tiên, bạn không chấm dứt kết nối. Vì vậy, nó phải có một) Được thả tự động hoặc b) Được chuyển qua và cập nhật mặc dù máy khách không sử dụng được.

Tôi giả sử b) do hiệu suất đạt được mà bạn mô tả. Tuy nhiên, đó có thể không phải là lý do duy nhất.

Bạn PHẢI đóng các kết nối của mình, tốt nhất là ở phía máy khách, nhưng bạn cũng phải thực hiện lỗi an toàn ở phía máy chủ. Nếu không, bạn đã có thêm crap chồng chất rằng máy chủ cơ sở dữ liệu của bạn phải xử lý cho đến khi nó được phát hành vào lúc biết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.