2011-09-08 31 views
5

Chúng tôi đang nhìn thấy tình huống mà kết nối cơ sở dữ liệu của chúng tôi từ org.apache.commons.dbcp.BasicDataSource đang hấp hối với ổ cắm lỗi viết:lợi nhuận DBCP đóng kết nối

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error 

Tất cả các nỗ lực tiếp theo để viết thư cho các kết nối thất bại, tất nhiên:

com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed. 

Sau khi cập nhật mã để bắt ngoại lệ như vậy và yêu cầu kết nối mới khi nó xảy ra, nó không thành công một lần nữa. Tôi có đúng là nghi ngờ rằng việc gọi số DataSource#getConnection() không thực sự đưa ra một kết nối mới mỗi khi nó được gọi? Không phải là nó chỉ tái sử dụng kết nối hiện có, được đóng lại?

Nếu tôi chính xác, cách đúng để vứt bỏ kết nối cũ và yêu cầu kết nối mới là gì?

EDIT: Dưới đây là một phiên bản succint nhiều hơn những gì tôi muốn biết:

Connection c1, c2; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c2 = DatabaseManager.getConnection(); 

Is "c1 c2 ==" một tuyên bố đúng không? Hoặc có hai kết nối được phân bổ? Và nếu đó là sau này, sẽ mã như thế này đại diện cho một "rò rỉ hồ bơi kết nối":

Connection c1; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c1 = DatabaseManager.getConnection(); 

Trả lời

10

Kết nối gộp lại đã bị đóng bởi DB. Điều đó có thể có nghĩa là 2 điều:

  1. Hồ bơi kết nối giữ kết nối mở quá lâu.
  2. DB đóng các kết nối sau một thời gian quá ngắn.

Về lý thuyết, tăng/giảm thời gian chờ ở hai bên để căn chỉnh nó sẽ khắc phục được sự cố.

Trên DBCP, đặt cược tốt nhất của bạn là xác thực kết nối trước khi trở về theo số testOnBorrow=true và cài đặt validationQuery, ví dụ: SELECT 1. Bạn có thể tìm các tùy chọn cấu hình trong số Tomcat JDBC data sources documentation.


Cập nhật theo cập nhật của bạn:

Dưới đây là một phiên bản succint nhiều hơn những gì tôi muốn biết:

Connection c1, c2; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c2 = DatabaseManager.getConnection(); 

Is "c1 c2 ==" một tuyên bố đúng? Hoặc có hai kết nối được phân bổ?

Đó là hai kết nối riêng biệt. Chỉ khi bạn gọi c1.close() thì có khả năng hợp lý là c2 trả về cùng một kết nối.

Và nếu đó là sau này, sẽ mã như thế này đại diện cho một "hồ bơi kết nối rò rỉ":

Connection c1; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c1 = DatabaseManager.getConnection(); 

Vâng, chắc chắn nó sẽ bị rò rỉ kết nối đầu tiên là nó chưa bao giờ được trở lại hồ bơi .Bạn nên luôn luôn đóng tất cả tài nguyên DB trong phạm vi ngắn nhất có thể trong khối try-finally. Tuy nhiên, một hồ bơi kết nối khá phong nha có thể cấu hình để gặt hái các kết nối bị bỏ rơi, nhưng điều này chắc chắn không nên được sử dụng như "giải pháp thay thế".

+0

Tôi cho rằng kết nối đã bị đóng do lỗi ghi ổ cắm được đề cập trước đây? Một khi nó được đóng lại, mặc dù, không gọi getConnection() có được một kết nối mới? –

+0

Không, đóng một kết nối gộp lại sẽ chỉ trả về kết nối với hồ bơi (đó là lý do tại sao bạn nên luôn đóng các kết nối trong 'final', hồ bơi khác có thể hết kết nối). Còn lại của việc xử lý các kết nối bị hỏng là lên đến hồ bơi mà bạn nên kiểm soát bằng cấu hình. Tuy nhiên, bạn nên nhận ra rằng DBCP là một hồ bơi được triển khai kém. Xem thêm http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0/3481821#3481821 – BalusC

+0

Nhưng nếu close() không bao giờ được gọi? Điều gì nếu mã chỉ giữ gọi getConnection()? hiện nó vẫn tái sử dụng kết nối cũ, đóng, hay nó có được một kết nối mới từ hồ bơi? –

0

Tôi cũng phải đối mặt với cùng một vấn đề. sau đó tôi nhận ra rằng tôi đã thực hiện nhiều cuộc gọi ajax không đồng bộ đã gây ra sự cố.

Tôi đã sắp xếp lại các cuộc gọi và nó đã khắc phục sự cố.

+0

Vui lòng đăng bất kỳ mã nào có liên quan cho những người tìm kiếm câu trả lời trong tương lai. – GibralterTop

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