2010-02-09 35 views
7

Giả sử rằng tôi có trang ASP.NET. Trong trình xử lý sự kiện tải trang, tôi mở một kết nối cơ sở dữ liệu và thực hiện một số xử lý. Nhưng sau khi xử lý xong, tôi không đóng kết nối một cách rõ ràng bằng cách gọi phương thức CLOSE của đối tượng kết nối.Đ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

Bây giờ khi xử lý trang ở phía máy chủ kết thúc, GC sẽ xử lý tất cả các biến trong trang của tôi và cũng có thể là đối tượng kết nối. Nhưng khi nó được xử lý, kết nối đã được mở trước đó có tự động đóng không? Ý tôi là, khi GC phân phối đối tượng kết nối, nó có tự động đóng kết nối được thiết lập với máy chủ cơ sở dữ liệu hay không; hoặc nó đơn giản vứt bỏ đối tượng kết nối và kết nối tại cơ sở dữ liệu vẫn mở, cho đến khi hết thời gian kết nối tại cơ sở dữ liệu và sau đó máy chủ cơ sở dữ liệu tự đóng kết nối?

+0

Khi bạn nói "biến" bạn có nghĩa là các trường thành viên trong lớp của bạn, hoặc bạn có nghĩa là các biến cục bộ. –

+0

Tôi có nghĩa là các biến cục bộ, giống như một số biến được khai báo bên trong một phương thức của một lớp .. –

+0

NGUY HIỂM !!!!!!!!! – jaywon

Trả lời

6

Các MSDN documentation là khá rõ ràng về vấn đề này:

Nếu SqlConnection đi ra khỏi phạm vi , nó sẽ không được đóng lại. Do đó, bạn phải đóng kết nối một cách rõ ràng bằng cách gọi Đóng hoặc Vứt bỏ. Đóng và Vứt bỏ là tương đương với chức năng.

Hoặc sử dụng các khối using để tự động hủy hoặc rõ ràng .Close() khối đó. Các khối using được ưu tiên.

Bằng cách thoát khỏi các kết nối, ứng dụng của bạn cuối cùng có thể hết kết nối khi có yêu cầu mới, dẫn đến lỗi. Tôi đã gặp phải một vấn đề như vậy trong một ứng dụng mà tôi đã gỡ lỗi. Các nhà phát triển ban đầu không đóng được kết nối một cách rõ ràng trên một vài trang và lưu lượng truy cập đủ cao khiến người dùng bắt đầu gặp lỗi. Tôi bọc các kết nối vi phạm trong khối using và sự cố đã biến mất.

+0

Điều thú vị là, có một vài sự khác biệt giữa Đóng và Vứt bỏ trên lớp SqlConnection. Bên cạnh đó tất nhiên sự khác biệt rõ ràng của việc có thể mở lại kết nối sau khi gọi Close, lớp SqlConnection không được hủy đăng ký từ hàng đợi finalizer (bằng cách gọi GC.SuppressFinalize (this)) trong một cuộc gọi để đóng. Điều này làm tăng áp lực lên GC. IMO này thực sự là một lỗi trong lớp SqlConnection. – Steven

2

Bạn nên sử dụng using khối, sau đó bạn sẽ không cần phải đặt câu hỏi:

using (var conn = new SqlConnection(connectionString)) 
{ 
    using (var cmd = new SqlCommand(commandText, conn)) 
    { 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) { /* ... */ } 
     } 
    } 
} 
+0

Nếu tôi sử dụng khối sử dụng, thì kết nối tại cơ sở dữ liệu có bị đóng bởi gcc không? –

+0

Không. Kết nối sẽ được đóng ở cuối khối sử dụng, ngay cả khi một ngoại lệ được ném vào trong khối. –

+1

Trên thực tế, kết nối với cơ sở dữ liệu thông thường sẽ không được đóng, nhưng nó chỉ đơn giản là quay trở lại hồ bơi kết nối.Nhưng khi không xử lý (hoặc đóng) một kết nối đúng cách, bạn đang cạn kiệt hồ bơi và cuối cùng sẽ nhận được một ngoại lệ thời gian chờ kết nối pool. – Steven

3

Connection vẫn mở. Nếu bạn có nhiều lần xem trang và nhiều kết nối mở, bạn có thể gặp lỗi 500.

3

Kết nối của bạn sẽ không bị đóng cho đến sau (không phải khi nào) đối tượng trang của bạn được hoàn thành và có thể mất một lúc. Nó sẽ rất dễ dàng để tối đa số lượng các kết nối có sẵn và bắt đầu nhận được lỗi.

1

kết nối của bạn sẽ không bị đóng trừ khi được GC chọn và nếu bạn có nhiều khách truy cập dẫn đến nhiều kết nối thì điều này có thể thật khủng khiếp. Ngoài ra nếu bạn cố gắng mở một kết nối mở nó sẽ ném lỗi, do đó bạn phải kiểm tra xem tốt hơn là viết nó bằng cách sử dụng khối hoặc đóng kết nối chính mình.

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