/** * Try to process a single transaction. Up to {@code MAX_ACCEPTABLE_FAIL_COUNT} attempts will be * made to process the transaction in cases where I/O errors or non-protocol server errors occur * during processing. Use of the underlying session is protected against concurrent use by other * threads by using the getSession/releaseSession features of this SessionManager's {@link * com.ausregistry.jtoolkit2.session.SessionPool}. This method guarantees that the session used * will be returned to the pool before the method returns. * * @throws FatalSessionException No session could be acquired to process the transaction. Check * the exception message and log records for details. * @throws IOException Every attempt to execute the transaction command failed due to an * IOException. This is the last such IOException. * @throws ParsingException Parsing of the response failed. Check the exception message for the * cause. * @throws CommandFailedException The acceptable limit on the number of failed commands due to * server error was exceeded in trying to process the command. This probably indicates a * server limitation related to the command being processed. * @throws IllegalStateException The SessionManager had been shutdown or not started up prior to * invoking this method. */ @Override public void execute(Transaction tx) throws FatalSessionException, IOException, ParsingException, CommandFailedException, IllegalStateException { debugLogger.finest("enter"); if (state == SMState.STOPPED) { throw new IllegalStateException(); } Command cmd = tx.getCommand(); Response response = tx.getResponse(); int failCount = 0; boolean isExecuted = false; Session session = null; // if only processing one transaction, get a new session for each // attempt in case the session fails mid-transaction. while (!isExecuted && state != SMState.STOPPED) { try { session = sessionPool.getSession(cmd.getCommandType()); StatsManager statsManager = session.getStatsManager(); statsManager.incCommandCounter(cmd.getCommandType()); tx.start(); session.write(cmd); isExecuted = true; session.read(response); tx.setState(TransactionState.PROCESSED); statsManager.recordResponseTime(cmd.getCommandType(), tx.getResponseTime()); Result[] results = response.getResults(); assert results != null; if (results != null) { for (Result result : results) { assert result != null; statsManager.incResultCounter(result.getResultCode()); int code = result.getResultCode(); switch (code) { case ResultCode.CMD_FAILED: throw new CommandFailedException(); case ResultCode.CMD_FAILED_CLOSING: default: throw new CommandFailedException(); } } } } catch (CommandFailedException cfe) { userLogger.warning(cfe.getMessage()); if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) { failCount++; } else { throw cfe; } } catch (IOException ioe) { userLogger.warning(ioe.getMessage()); userLogger.warning("net.socket.closed"); session.close(); if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) { failCount++; } else { throw ioe; } } catch (InterruptedException ie) { // if interrupted by shutdown, then started will be false // Note: this still enters the finally block continue; } catch (SessionConfigurationException sce) { throw new FatalSessionException(sce); } catch (SessionOpenException soe) { throw new FatalSessionException(soe); } finally { sessionPool.releaseSession(session); } } if (!isExecuted && state == SMState.STOPPED) { throw new IllegalStateException(); } debugLogger.finest("exit"); }