高性能 Oracle JDBC 编程了解如何利用连接和语句池特性来提高 Oracle 驱动的 JDBC 程序的性能。作者:Yuli Vasiliev2009 年 4 月发布使用诸如连接池和语句池等池技......
高可用性和高性能
需要强调的是,UCP 支持与 Oracle 真正应用集群 (RAC) 无关的新的 JDBC 4.0 高可用性和高性能特性(如池刷新和连接验证)。因此,不需要 Oracle RAC 数据库。
而且,UCP 能够验证借用连接。验证借用连接是一项非常有用的技术,因为它使您能够在使用前检查连接是否有效。为解决该问题,UCP JDBC 连接池实例中添加了布尔类型的 ValidateConnectionOnBorrow 属性,您需要使用 setValidateConnectionOnBorrow 方法将其设为 true:
pds.setValidateConnectionOnBorrow(true);
然后,需要指定一条要执行的 SQL 语句,以确保该连接仍然有效。可以使用 setSQLForValidateConnection 方法完成此操作:
pds.setSQLForValidateConnection("select user from dual");
使用 Oracle JDBC 驱动程序时,无需设置 SQLForValidateConnection 属性 — 池将在内部执行 ping 操作来测试该借用连接的有效性。
验证借用连接是一件非常有益的事情,但是如果在成功验证借用连接后,连接失效该怎么办?有没有方法在借用后验证连接?为解决此问题,JDBC 4.0 规范将 isValid 方法添加到 Connection 接口,使您能够在需要的时候测试连接的有效性。
更进一步地讲,UCP for JDBC 提供了 oracle.ucp.jdbc.ValidConnection 接口,其中包括两个方法:isValid 和 setInvalid。与使用递归或迭代(循环)实现的重试机制结合使用时,这两个方法尤为有用。例如,您可以实现一个借用连接然后使用连接的方法,对其自身使用一个递归调用以防由于连接失效导致操作无法完成。实现这样的递归机制时需要记住的是,必须能够限制要进行的递归次数,并且每进行一次新的递归调用必须减少该次数,从而避免可能出现的无限循环。
以下是作为示例的一个简单程序,将演示如何结合使用 oracle.ucp.jdbc.ValidConnection 接口方法与基于递归的重试机制。
/*
*An example of validating connections on borrow;
*this also shows the use of the ValidConnection interface's methods:
*isValid and setInvalid methods in combination with a retry mechanism
*/
import java.sql.*;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.ValidConnection;
import javax.naming.*;
import java.util.Hashtable;
public class ConnectionValidating {
public static void main(String argv[]) {
PoolDataSource pds;
//Looking up for the jdbc/HRPool pool-enabled data source registered in JNDI tree
...
//for actual code see the JNDI lookup example
//discussed in the Borrowing a Connection with JNDI section earlier
...
try {
//Instructing the pool to validate connections on borrow
pds.setValidateConnectionOnBorrow(true);
//Calling the getUser method that borrows a connection from the pool
//limiting the number of recursive calls to 3
System.out.println("\nConnected as :" getUser(pds, 3));
}
catch (SQLException eSQL) {
System.out.println("\nSQLException: " eSQL);
return;
}
}
//This method borrows a connection from the pool and will make a recursive call
//if it turns out that the borrowed connection has become unusable
private static String getUser (PoolDataSource pds, int recursiveCalls) throws SQLException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String user = null;
try {
//Borrowing a connection from the pool
conn = pds.getConnection();
//Working with the connection
stmt = conn.createStatement();
rs = stmt.executeQuery("select user from dual");
while(rs.next())
user = rs.getString(1);
if (conn != null)
conn.close();
}
catch (SQLException eSQL) {
if (recursiveCalls > 0 && !((ValidConnection) conn).isValid()) {
System.out.println("\nConnection is no longer valid: " eSQL);
//Calling setInvalid often leads to an exception
//so it's a wise idea to put it in a separate try block
try {
((ValidConnection) conn).setInvalid();
} catch (SQLException conEx) {
System.out.println("\nInvalidating failed: " conEx);
}
conn.close();
conn = null;
System.out.println("\nRetrying to obtain a new connection");
//making a recursive call to getUser in an attempt to obtain a valid connection
//the number of recursive calls allowed is reduced by 1
user = getUser(pds, recursiveCalls - 1);
} else {
System.out.println("\nSQLException: " eSQL);
}
}
finally {
return user;
}
}
}
6/14 首页 上一页 4 5 6 7 8 9 下一页 尾页 |