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
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".
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ỏ.
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ệ. –
@ 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
@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. –
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.
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.
- 1. Điều gì sẽ xảy ra với cơ sở dữ liệu Sqlite khi ứng dụng bị xóa
- 2. Điều gì sẽ xảy ra nếu tôi không đóng cơ sở dữ liệu trong Android?
- 3. Điều gì sẽ xảy ra khi kết nối với MongoDB không bị đóng?
- 4. Chuỗi kết nối DB trong Web.config để sử dụng cơ sở dữ liệu .mdf đính kèm sẽ không hoạt động
- 5. Đính kèm cơ sở dữ liệu không cho máy chủ
- 6. Điều kiện kết nối với cơ sở dữ liệu
- 7. Điều gì xảy ra nếu tôi để lại kết nối cơ sở dữ liệu mở trong trang web ASP.NET
- 8. Không thể kết nối với cơ sở dữ liệu .mdf
- 9. Kết nối cơ sở dữ liệu CodeIgniter không được đóng
- 10. Tín hiệu Qt và Khe cắm được kết nối hai lần ... điều gì sẽ xảy ra?
- 11. Điều gì sẽ xảy ra khi auto_increment trên cột nguyên đạt đến max_value trong cơ sở dữ liệu?
- 12. Cơ sở dữ liệu và kết nối
- 13. Điều gì là sai với chuỗi kết nối cơ sở dữ liệu này?
- 14. Kết nối với cơ sở dữ liệu oracle với C++
- 15. Kết nối với cơ sở dữ liệu MySQL với RMySQL
- 16. Kết nối cơ sở dữ liệu không đồng nhất
- 17. Điều gì sẽ xảy ra nếu dịch vụ dữ liệu đám mây Parse không thành công?
- 18. Kết nối với Cơ sở dữ liệu Sharepoint qua PHP
- 19. Đang cố gắng để tách đính kèm cơ sở dữ liệu - không thể acces db sau
- 20. Cố gắng đính kèm một cơ sở dữ liệu được đặt tên tự động cho tệp .mdf không thành công
- 21. Điều gì gây ra 'không thể kết nối với nguồn dữ liệu' cho pyodbc?
- 22. Kết nối JPA với cơ sở dữ liệu H2
- 23. Cảnh báo kết nối ActiveRecord. (Kết nối cơ sở dữ liệu sẽ không tự động bị đóng)
- 24. Tôi có nên đặt kích thước nhóm tối đa trong chuỗi kết nối cơ sở dữ liệu không? Điều gì xảy ra nếu tôi không?
- 25. Điều gì sẽ xảy ra khi kết nối Npgsql đạt đến mức tối đa
- 26. cách kết nối F # với cơ sở dữ liệu MySQL?
- 27. Điều gì sẽ xảy ra nếu các kết nối MySQL liên tục không đóng trên các trang PHP?
- 28. Kết nối với hai cơ sở dữ liệu
- 29. Kết nối tổng hợp với cơ sở dữ liệu Access
- 30. Danh sách Cơ sở dữ liệu được đính kèm bằng lệnh SELECT trong SQLite
"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
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
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