📄 ch08.html
字号:
<PRE CLASS="CODE"><A NAME="pgfId-1087735"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087736"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087737"></A> public boolean validate() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087738"></A> try {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087739"></A> conn.getMetaData();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087740"></A> } catch (Exception e) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087741"></A> return false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087742"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087743"></A> return true;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087744"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087745"></A> public boolean inUse() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087746"></A> return inuse;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087747"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087748"></A> public long getLastUse() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087749"></A> return timestamp;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087750"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087751"></A> public void close() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087752"></A> pool.returnConnection(this);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087753"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087754"></A> protected void expireLease() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087755"></A> inuse=false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087756"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087757"></A> protected Connection getConnection() {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087758"></A> return conn;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087759"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087760"></A> public PreparedStatement prepareStatement(String sql) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087761"></A> return conn.prepareStatement(sql);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087762"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087763"></A> public CallableStatement prepareCall(String sql) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087764"></A> return conn.prepareCall(sql);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087765"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087766"></A> public Statement createStatement() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087767"></A> return conn.createStatement();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087768"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087769"></A> public String nativeSQL(String sql) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087770"></A> return conn.nativeSQL(sql);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087771"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087772"></A> public void setAutoCommit(boolean autoCommit) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087773"></A> conn.setAutoCommit(autoCommit);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087774"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087775"></A> public boolean getAutoCommit() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087776"></A> return conn.getAutoCommit();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087777"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087778"></A> public void commit() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087779"></A> conn.commit();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087780"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087781"></A> public void rollback() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087782"></A> conn.rollback();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087783"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087784"></A> public boolean isClosed() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087785"></A> return conn.isClosed();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087786"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087787"></A> public DatabaseMetaData getMetaData() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087788"></A> return conn.getMetaData();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087789"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087790"></A> public void setReadOnly(boolean readOnly) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087791"></A> conn.setReadOnly(readOnly);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087792"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087793"></A> public boolean isReadOnly() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087794"></A> return conn.isReadOnly();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087795"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087796"></A> public void setCatalog(String catalog) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087797"></A> conn.setCatalog(catalog);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087798"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087799"></A> public String getCatalog() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087800"></A> return conn.getCatalog();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087801"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087802"></A> public void setTransactionIsolation(int level) throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087803"></A> conn.setTransactionIsolation(level);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087804"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087805"></A> public int getTransactionIsolation() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087806"></A> return conn.getTransactionIsolation();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087807"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087808"></A> public SQLWarning getWarnings() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087809"></A> return conn.getWarnings();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087810"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087811"></A> public void clearWarnings() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087812"></A> conn.clearWarnings();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087813"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087814"></A>}</PRE></DIV><DIV><H5 CLASS="B"><A NAME="pgfId-1087815"></A>Deadlocks and Hangs</H5><P CLASS="Body"><A NAME="pgfId-1087820"></A><A NAME="marker-1087816"></A><A NAME="marker-1087817"></A><A NAME="marker-1087818"></A><A NAME="marker-1087819"></A>While many client and server databases have graceful ways to handle deadlocks and hangs so you do not have to write code to handle these situations, many of the newer, lightweight distributed databases are not so well equipped. The connection pool class provides a <A NAME="marker-1087821"></A>dead connection reaper to handle these situations. </P><P CLASS="Body"><A NAME="pgfId-1087823"></A>The <EM CLASS="CODE">ConnectionReaper</EM><A NAME="marker-1087822"></A> class in the <EM CLASS="CODE">JDCConnectionPool</EM> class file decides a connection is dead if the following conditions are met. </P><UL><LI CLASS="BL"><A NAME="pgfId-1087824"></A>The connection is flagged as being in use.</LI><LI CLASS="BL"><A NAME="pgfId-1087825"></A>The connection is older than a preset connection time out. </LI><LI CLASS="BL"><A NAME="pgfId-1087826"></A>The connection fails a validation check. </LI></UL><P CLASS="Body"><A NAME="pgfId-1087827"></A>The validation check runs a simple SQL query over the connection to see if it throws an exception. In this example, the validation method requests the high-level description of the database tables. If a connection fails the <A NAME="marker-1087828"></A>validation test, it is closed, a new connection is initiated to the database, and added to the connection pool. </P><PRE CLASS="CODE"><A NAME="pgfId-1087829"></A>public boolean validate() { try { conn.getMetaData(); }catch (Exception e) { return false; } return true;}</PRE></DIV><DIV><H5 CLASS="B"><A NAME="pgfId-1087830"></A>Closing Connections</H5><P CLASS="Body"><A NAME="pgfId-1087831"></A>The connection is returned to the connection pool when the calling program calls the <EM CLASS="CODE">JDCConnection.close</EM> method in its finally clause. </P><PRE CLASS="CODE"><A NAME="pgfId-1087832"></A>public void close() throws SQLException { pool.returnConnection(this);}</PRE></DIV><DIV><H5 CLASS="B"><A NAME="pgfId-1087833"></A>Example Application</H5><P CLASS="Body"><A NAME="pgfId-1087834"></A>You use a connection pool in an application in a similar way to how you would use any other JDBC driver. The <EM CLASS="CODE">RegistrationBean</EM> code for this chapter illustrates this point, and is adapted from the auction house Enterprise JavaBeans example described in Chapters 1-3. </P><P CLASS="Body"><A NAME="pgfId-1087835"></A>When the first <EM CLASS="CODE">RegistrationBean</EM> object is created, it creates one static instance of the <EM CLASS="CODE">JDCConnectionDriver</EM> class. This static driver object registers itself with the <EM CLASS="CODE">DriverManager</EM> in the <EM CLASS="CODE">JDCConnectionDriver</EM> constructor making it available for connection requests to all <EM CLASS="CODE">RegistrationBean</EM> objects created by the client application. </P><P CLASS="Body"><A NAME="pgfId-1087836"></A>Passing the URL as <EM CLASS="CODE">jdbc:jdc:jdcpool</EM> in the <EM CLASS="CODE">getConnection</EM> method lets the <EM CLASS="CODE">DriverManager</EM> match the <EM CLASS="CODE">getConnection</EM> request to the registered driver. The <EM CLASS="CODE">DriverManager</EM> uses simple <EM CLASS="CODE">String</EM> matching to find an available driver that can handle URLs in that format. </P><PRE CLASS="CODE"><A NAME="pgfId-1087839"></A><A NAME="marker-1087837"></A><A NAME="marker-1087838"></A>package registration;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087840"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087841"></A>import java.rmi.RemoteException;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087842"></A>import javax.ejb.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087843"></A>import java.util.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087844"></A>import java.text.NumberFormat;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087845"></A>import java.sql.*;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087846"></A> </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087847"></A>//uses our connection pool</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087848"></A>public class RegistrationBean implements EntityBean {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087849"></A> protected transient EntityContext ctx;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087850"></A> public String theuser, password, creditcard, emailaddress;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087851"></A> public double balance;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087852"></A> static {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087853"></A> try {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087854"></A> new pool.JDCConnectionDriver("COM.cloudscape.core.JDBCDriver", </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087855"></A> "jdbc:cloudscape:ejbdemo","none", "none"); </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087856"></A> } catch(Exception e){}</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087857"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087858"></A> public Connection getConnection() throws SQLException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087859"></A> return DriverManager.getConnection("jdbc:jdc:jdcpool");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087860"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087861"></A> public boolean verifyPassword(String password) throws RemoteException { </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087862"></A> if(this.password.equals(password)) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087863"></A> return true;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087864"></A> } else {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087865"></A> return false;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087866"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087867"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087868"></A> public String getEmailAddress() throws RemoteException { </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087869"></A> return emailaddress;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087870"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087871"></A> public String getUser() throws RemoteException { </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087872"></A> return theuser;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087873"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087874"></A> public int adjustAccount(double amount) throws RemoteException { </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087875"></A> balance=balance+amount;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087876"></A> return(0);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087877"></A> }</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087878"></A> public double getBalance() throws RemoteException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087879"></A> return balance;</PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -