2012-06-22 33 views
7

Tôi mới sử dụng Java (Tôi đang sử dụng Java 6). Tôi đã sử dụng mẫu thiết kế dưới đây cho tất cả các POJO và Java servlet của tôi để truy cập cơ sở dữ liệu Oracle 11G thông qua máy chủ web GlassFish 3.1.2.Java/JDBC: Mẫu thiết kế tốt nhất để đóng kết nối cơ sở dữ liệu khi ngoại lệ xảy ra

Tôi nhận được lỗi cơ sở dữ liệu liên tục (ORA-12519) khi tất cả các quy trình có sẵn (hoặc phiên, không chắc chắn sự khác biệt) được sử dụng, khiến tôi suy nghĩ bằng cách nào đó các quy trình không được ứng dụng phát hành.

Nhìn vào mẫu thiết kế bên dưới, có cách nào tốt hơn để đảm bảo rằng kết nối JDBC tới cơ sở dữ liệu được phát hành trong trường hợp ngoại lệ không? Ví dụ: tôi cũng nên đặt mã if (conn != null) conn.close(); INSIDE khối catch? Hoặc, là có một mẫu thiết kế tốt hơn? Cảm ơn trước cho bất kỳ ý kiến ​​/ gợi ý.

public String MyFunction() throws Exception {  

    Connection conn; 
    CallableStatement cs; 

    try { 

     Context context = new InitialContext(); 
     DataSource ds = (DataSource)context.lookup("jdbc/MyPool"); 
     conn = ds.getConnection();   

     cs = conn.prepareCall("{call my_sproc (?)}"); 

     cs.registerOutParameter(1, Types.VARCHAR); 

     cs.execute(); 

     String outParam = cs.getString(1); 

     if (conn != null) // close connection 
     conn.close(); 

    } catch (Exception e) { 
     outParam = "an error occurred"; 
    } 
    return outparam; 
} 
+0

Lưu ý rằng nó cũng có thể thực hành tốt để đóng resultsets và báo cáo. Đây là một liên kết hữu ích (xem câu trả lời của Stefan Schweizer trong liên kết cho mẫu thiết kế tốt): http://stackoverflow.com/questions/103938/resultset-not-closed-when-connection-closed – ggkmath

Trả lời

29
if (conn != null) // close connection 
     conn.close(); 

Tại dòng này connkhông có thể được null. Các mô hình phổ biến nhất, cho đến Java 6 là:

Connection conn = null; 
try { 
    // initialize connection 
    // use connection 
} catch { 
    // handle exception 
} finally { 
    if (conn != null) { 
    try { conn.close(); } catch (Exception e) { /* handle close exception, quite usually ignore */ } 
    } 
} 

Với Java 7 này sẽ trở nên ít cồng kềnh với try-with-resource cấu trúc của nó. Mã trên có thể thay đổi thành ngắn hơn nhiều

try (Connection conn = createConnection()) { 
    // use connection 
} catch { 
    // handle exception 
} 
// close is not required to be called explicitly 
+1

Cảm ơn Variable Variable, khi bạn nói "lên cho đến khi Java 6" bạn có nghĩa là "lên đến và bao gồm Java 6" (đó là những gì tôi đang sử dụng)? Tôi cho là vậy. Ngoài ra, khi bạn nói "khá thường bị bỏ qua", bạn đang chỉ nói đến 'try ... catch' trong khối cuối cùng (có nghĩa là' if (conn! = Null) conn.close(); 'luôn luôn là ở đó, phải không?)? Tại sao mọi người thường bỏ qua xử lý ngoại lệ trong khối cuối cùng để đóng kết nối? – ggkmath

+0

Có, các ngoại lệ từ 'connection.close()' thường bị bỏ qua hoặc được ghi lại nhiều nhất nhưng không được xử lý theo bất kỳ cách nào khác :) Tôi không biết tại sao; Tôi chưa bao giờ thực sự nhìn thấy một trường hợp ngoại lệ. –

+0

OK, tôi có thể sẽ đăng nhập, cảm ơn! – ggkmath

4

Sử dụng finally chặn luôn để giải phóng tài nguyên.

Khối cuối cùng luôn thực thi khi khối thử thoát. Điều này đảm bảo rằng khối cuối cùng được thực hiện ngay cả khi một ngoại lệ không mong muốn xảy ra.

try { 

     Context context = new InitialContext(); 
     DataSource ds = (DataSource)context.lookup("jdbc/MyPool"); 
     conn = ds.getConnection();   

     cs = conn.prepareCall("{call my_sproc (?)}"); 

     cs.registerOutParameter(1, Types.VARCHAR); 

     cs.execute(); 

     String outParam = cs.getString(1); 


    } catch (Exception e) { 
     outParam = "an error occurred"; 
    } 
finally { 
     conn.close(); 
    } 
+0

Cảm ơn Kazekage, 'conn. close() 'dòng mã trong khối cuối cùng đưa ra một lỗi nếu kết nối chưa được mở hoặc bất kỳ lý do nào khác? Nếu vậy, tôi có nên sử dụng câu lệnh 'if (conn! = Null)' ở trên trong khối cuối cùng không? – ggkmath

+0

Nếu bạn nghi ngờ rằng 'conn.close()' lại một lần nữa sẽ đưa ra một lỗi, bao quanh nó với 'try catch finally'. –

+1

@ggkmath vâng bạn cần kiểm tra 'conn! = Null'; nó có thể là null nếu 'ds.getConnection()' ném ngoại lệ.Và cho dù bạn nghi ngờ hay không, bạn cần phải đặt 'close()' trong 'try/catch/finally'; phương pháp khác phải bao gồm nó trong mệnh đề 'throws' không tốt. –

2

java se 7 hỗ trợ tính năng thử nghiệm với tài nguyên. tạo ra cuối cùng cho bạn. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

khối cuối cùng sẽ đóng tài nguyên được định vị trong thử. như bạn đang sử dụng các từ khóa sử dụng trong C#

tuy nhiên người dùng đang sử dụng java SE6 ... Xem các tùy chọn của người dùng khác :)

QUAN TRỌNG: Báo cáo sử dụng nên được đóng lại quá.

+0

Tham khảo tuyệt vời cho người dùng java se 7, cảm ơn! – ggkmath

+0

Tôi đã không đọc nhưng biến Miserable của người dùng đã nói về việc thử-với-tài nguyên nữa. – brunoss

+0

Tôi sẽ xác nhận rằng sau 1 phút nhưng tôi đoán bạn cần đóng các câu lệnh – brunoss

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