2009-06-19 67 views
7

Trước đó hôm nay tôi đã tìm thấy một lỗi trong một trong các dự án của chúng tôi - có một sự kết hợp với cơ sở dữ liệu không bao giờ bị đóng, nghĩa là phương thức Close() không bao giờ được gọi. Tuy nhiên, khi tôi đóng ứng dụng, kết nối được đóng lại (kiểm tra trong phòng quản lý sql nhiều lần). Tại sao?Điều gì sẽ xảy ra với kết nối cơ sở dữ liệu không được đính kèm?

Trả lời

4

Kết nối sẽ đóng khi ứng dụng thoát. Đọc trên SqlConnection's Finalize. Từ tài liệu của MSDN cho Object.Finalize:

"Trong khi tắt miền ứng dụng, Finalize tự động được gọi trên các đối tượng không được miễn hoàn thành, ngay cả những đối tượng vẫn có thể truy cập".

+0

"Nếu SqlConnection nằm ngoài phạm vi, nó sẽ không bị đóng. Do đó, bạn phải đóng kết nối rõ ràng bằng cách gọi Đóng hoặc Vứt bỏ." - đó là từ msdn là tốt, không có nghĩa là kết nối có thể không được đóng nếu bạn không gọi Close()? – agnieszka

+0

Bạn về cơ bản có thể thực hiện Đóng, Vứt bỏ hoặc sử dụng() {}, như bạn vẫn nên làm. Khi ứng dụng đóng các kết nối cũng sẽ đóng, vì lý do tôi đã nêu trong câu trả lời của tôi. – RichardOD

+0

Ngoài ra, bất kỳ lúc nào GC quyết định hoàn thành các kết nối, thì chúng cũng sẽ bị đóng. – RichardOD

1

Kết nối SQL tốn kém để tạo và ADO.NET sử dụng kỹ thuật được gọi là kết nối tổng hợp cho phép sử dụng lại chúng.

Trích từ MSDN:

Nó được khuyên bạn luôn đóng kết nối khi bạn đã kết thúc sử dụng nó để nó sẽ được trở lại hồ bơi kết nối và được tái sử dụng.

Nếu kích thước hồ bơi tối đa là đạt được và không có kết nối khả dụng nào là , yêu cầu được xếp hàng đợi. Sau đó, thiết bị lưu trữ sẽ cố gắng giành lại bất kỳ kết nối nào cho đến khi hết thời gian chờ (mặc định là 15 giây). Nếu nhân viên không thể đáp ứng yêu cầu trước thời gian kết nối , ngoại lệ sẽ bị loại bỏ.

+1

Trên thực tế, vì kết nối pool, một kết nối SQL chưa bao giờ thực sự bị đóng - nó chỉ được trả lại cho pool để được tái sử dụng khi bạn gọi Close. Nó sẽ đóng khi miền ứng dụng bị hủy khi bạn thoát khỏi ứng dụng. Vì vậy, nếu bạn không bao giờ gọi Đóng kết nối sẽ không được sử dụng lại và khi hồ bơi cạn kiệt, bạn sẽ nhận được một ngoại lệ. –

+0

@ darin- không bao giờ thực sự đóng không chính xác. Sau một số lượng không hoạt động nhất định, kết nối sẽ bị đóng, nhưng đó chỉ là việc đánh bạc. – RichardOD

+1

@RichardOD, tôi sẽ không nói rằng nó là nitpicking. Tôi thực sự không biết thực tế này. Cảm ơn bạn rất nhiều vì sự chính xác này. –

1

Khi bạn thoát khỏi ứng dụng theo cách thông thường, tôi hy vọng các finalizers sẽ chạy. Họ sẽ đóng kết nối nếu nó vẫn mở. Chỉ cần không phụ thuộc vào điều này: nó có thể mất một lúc trước khi finalizers được chạy trong hoạt động bình thường của ứng dụng của bạn, vì vậy bạn sẽ được giữ quá nhiều kết nối mở.

Khi ứng dụng gặp sự cố, có thể trình kết thúc sẽ không chạy, để kết nối mở trong suốt thời gian tồn tại của ứng dụng.

2

Một điều cần ghi nhớ ở đây là trong .Net, bạn có thể bọc các kết nối của bạn trong một khối sử dụng, và điều đó sẽ đóng và xử lý các kết nối của bạn cho bạn. Vì vậy, việc thiếu một Đóng rõ ràng() không phải là một điều xấu nếu bạn đã có khối sử dụng của bạn có ...

// this using block will auto close & dispose your connection... 
using (var conn = new SqlConnection(...)) 
{ 
    conn.Open(); 
    // database code here with no explicit close 

} 

đó là tương đương với chức năng của một thử/khối finally với một conn.close cuối cùng. Nhiều nhà phát triển bỏ qua các khối sử dụng - đảm bảo bạn không làm như vậy trong trường hợp này.

Nếu bạn viết lại mã để đóng kết nối - thực hành tốt Sử dụng các khối xung quanh tất cả các đối tượng cơ sở dữ liệu của bạn (kết nối, lệnh, trình đọc) để đảm bảo rằng chúng đang đóng và xử lý khi chúng nằm ngoài phạm vi của khối sử dụng. Tôi chắc chắn sẽ đề nghị viết những người vào mã của bạn thay vì chỉ conn.Close() khi cần thiết.

+0

Yeap đó là cách tôi làm điều đó. Nếu bạn sử dụng FXCop bạn sẽ không bao giờ có một vấn đề vì nó cảnh báo bạn về việc không gọi Dispose. – RichardOD

+0

Không có khối sử dụng, tôi biết về chúng. – agnieszka

+0

và nó không phải là câu trả lời cho câu hỏi – agnieszka

Các vấn đề liên quan