public Object invoke(MethodInvocation invocation) throws Throwable { if (!StringUtils.equalsIgnoreCase(invocation.getMethod().getName(), "getConnection")) { return invocation.proceed(); } try { return invocation.proceed(); // need to check with detecting sql? } catch (Throwable t) { if (t instanceof SQLException) { // we use SQLStateSQLExceptionTranslator to translate SQLExceptions , but it doesn't mean it will work as we expected, // so maybe more scope should be covered. we will check out later with runtime data statistics. DataAccessException dae = sqlExTranslator.translate( "translate to check whether it's a resource failure exception", null, (SQLException) t); if (dae instanceof DataAccessResourceFailureException) { logger.warn("failed to get Connection from data source with exception:\n{}", t); doSwap(); return invocation.getMethod().invoke(targetSource.getTarget(), invocation.getArguments()); } } // other exception conditions should be handled by application, // 'cause we don't have enough context information to decide what to do here. throw t; } }
private void doSwap() { synchronized (targetSource) { DataSource target = (DataSource) getTargetSource().getTarget(); if (target == mainDataSource) { logger.warn("hot swap from '" + target + "' to '" + standbyDataSource + "'."); getTargetSource().swap(standbyDataSource); } else { logger.warn("hot swap from '" + target + "' to '" + mainDataSource + "'."); getTargetSource().swap(mainDataSource); } } }
private void doSwap() { synchronized(hotSwapTargetSource){ DataSource target = (DataSource) getHotSwapTargetSource().getTarget(); if (target == masterDataSource) { getHotSwapTargetSource().swap(standbyDataSource); currentDetectorDataSource = standbyDetectorDataSource; } else { getHotSwapTargetSource().swap(masterDataSource); currentDetectorDataSource = masterDetectorDataSource; } } }