The DBCP project has some ability to detect database failover and refresh pools of connections, but it isn't too hard to institute one yourself in a custom datasource. I haven't used the DBCP but have done custom datasource failover, You can choose your level of paranoia ("select 2+2" from every connection before yielding it out of the pool, every second grab a connection and test it, etc).
The case where you have an open Connection attached to a PB is going to be tough -- you can catch Exception or Throwable anywhere and get it to compile, but that is hideous. In the past it has been acceptable for me to allow the edge case to fail as database failover is very rare -- and an exception with note on the error page saying "a database problem occured, it may just be temporary. It is okay to use the back button and try your action again" is acceptable.
If that isn't acceptable the solution you may need is to wrap the JDBC connection itself, in which case that means wrapping the JDBC Datasource. This isn't really difficult to do -- I have worked with (though didn't originally implement, I work with the guy who did) custom PostgreSQL drivers to handle similar types of issues.
In a custom driver you would probably just do the paranoid testing before calls that talk to the database, similar to the pool level testing but you can also catch exceptions and handle them internally. For the record I think that is a bit paranoid, but if you have a "full failover and no one notices" requirement you are in paranoid space =)
OJB, afaik, trusts the Connection instances it pulls from its Driver or Datasource to not have the database behind them go away without notice.
-Brian
On Dec 10, 2003, at 11:10 PM, Stephen Ting wrote:
Can anybody give me some hints on how to design a failover system with OJB in appserver to database layer?
I use OJB PB api within a session bean. The following code snippet
roughly show roughly what i did. whenever the
link from the application server to the database is down. I was not able
catch the exception at the session bean to handle
it properly. and the sql exception is propagate to the presentation
layer. Does anybody have any experience how to design
an automatic failover in this scenario. I try to catch SQLException, but
ecplise won't compile.. it said, the catch block
is unreachable.
try{ ... broker = getBroker(); Collection col = broker.getCollectionByQuery(query); ... }catch(PersistenceBrokerException ex){ ... }
any help are very much appreciated.. thanks
Regards,
Stephen Ting
2003-12-11 11:43:30,156 INFO [STDOUT]
[org.apache.ojb.broker.accesslayer.JdbcAccessImpl] ERROR:
2003-12-11 11:43:30,156 INFO [STDOUT] SQLException during the execution
of the query (for a my.com.shinyang.eply.model.LogSupplier):
Communication link failure: java.io.IOException, underlying cause:
Unexpected end of input stream
** BEGIN NESTED EXCEPTION **
java.io.IOException MESSAGE: Unexpected end of input stream
STACKTRACE:
java.io.IOException: Unexpected end of input stream
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1405)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1775)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1020)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1109)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2030)
at
com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java: 156
3)
at
org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(W r
appedPreparedStatement.java:302)
at
org.apache.ojb.broker.accesslayer.JdbcAccessImpl.executeQuery(Unknown
Source)
at org.apache.ojb.broker.accesslayer.RsQueryObject.performQuery(Unknown
Source)
at org.apache.ojb.broker.accesslayer.RsIterator.<init>(Unknown Source)
at
org.apache.ojb.broker.core.RsIteratorFactoryImpl.createRsIterator(Unkno w
n Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getRsIteratorFromQuery (
Unknown Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getIteratorFromQuery(U n
known Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(U n
known Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(U n
known Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(U n
known Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(U n
known Source)
at
org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQ u
ery(Unknown Source)
at
org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQ u
ery(Unknown Source)
at
my.com.shinyang.eply.service.ejb.SearchSessionBean.doSearch(SearchSessi o
nBean.java:308)
at
my.com.shinyang.eply.service.ejb.SearchSessionBean.doSearch(SearchSessi o
nBean.java:373)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.ja v
a:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccesso r
Impl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(Sta t
elessSessionContainer.java:683)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke (
CachedConnectionInterceptor.java:185)
at
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(Statel e
ssSessionInstanceInterceptor.java:72)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterc e
ptor.java:84)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxIntercepto r
CMT.java:267)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java: 128)
at
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.ja v
a:118)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactory F
inderInterceptor.java:122)
at
org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSession C
ontainer.java:331)
at org.jboss.ejb.Container.invoke(Container.java:700)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.ja v
a:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccesso r
Impl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanD i
spatcher.java:284)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at
org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
at
org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java: 9
0)
at
org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.ja v
a:46)
at
org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
at
org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSession I
nterceptor.java:100)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
at $Proxy60.doSearch(Unknown Source)
at
my.com.shinyang.eply.bd.SearchDelegateEJBImpl.doSearch(SearchDelegateEJ B
Impl.java:70)
at
my.com.shinyang.eply.syl.webdesk.SylSupplierAction.searchSupplier(SylSu p
plierAction.java:254)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.ja v
a:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccesso r
Impl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction. j
ava:280)
at
org.apache.struts.actions.DispatchAction.execute(DispatchAction.java: 216
)
at
org.apache.struts.action.RequestProcessor.processActionPerform(RequestP r
ocessor.java:484)
at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java :
274)
at
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applic a
tionFilterChain.java:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFil t
erChain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperVal v
e.java:256)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 4
80)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextVal v
e.java:191)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:643)
at
org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurit y
MgrRealm.java:220)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authenticato r
Base.java:553)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.j a
va:246)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(Containe r
StatsValve.java:76)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 4
80)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java: 241
6)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.jav a
:180)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:643)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherV a
lve.java:171)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.jav a
:172)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityA s
sociationValve.java:65)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java: 577
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:641)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 4
80)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve .
java:174)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext. i
nvokeNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 4
80)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java: 60
1)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process C
onnection(Http11Protocol.java:392)
at
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java: 56
5)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPoo l
.java:619)
at java.lang.Thread.run(Thread.java:534)
** END NESTED EXCEPTION **
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
