Class StatelessJdbcListener
- All Implemented Interfaces:
FrankElement, HasApplicationContext, HasName, HasPhysicalDestination, IConfigurable, IListener<Serializable>, IPeekableListener<Serializable>, IPullingListener<Serializable>, IScopeProvider, NameAware, TransactionAware, ConfigurableLifecycle, org.springframework.beans.factory.Aware, org.springframework.context.ApplicationContextAware, org.springframework.context.Lifecycle, org.springframework.context.Phased, org.springframework.context.SmartLifecycle
This listener does not maintain any processing-state in the table, like the JdbcTableListener or MessageStoreListener do. To prevent messages
from being picked up by multiple instances of the same listener, queries will always use SELECT .... FOR UPDATE to make sure the rows are locked.
In transactional Receivers this will keep the row locked for the entire duration of the pipeline, potentially stalling
other processes. Because there is no state-change management, everything will happen in a single transaction.
To prevent the same message being picked up again after the pipeline completes, you should either remove it, or update it so that it no longer matches the SELECT
conditions of the query. You can either:
- Use a
FixedQuerySenderin your pipeline to delete the row - Use a
setAfterProcessQuery(String)which is automatically executed when the pipeline finishes - Use a
setAfterSelectQuery(String)which can delete the row immediately after it has been selected and read
The setSelectQuery(String) and AbstractJdbcListener.setPeekQuery(String) will be automatically modified to be SELECT ... FOR UPDATE or SELECT ... FOR SHARE SKIP LOCKED
queries. With some databases this means you cannot grouping queries or queries using COUNT(...), SUM(...) or similar statements.
This listener does not do any validation of the queries in configuration, or when opened. Any errors in your queries can result in a heavy load on the
system as queries are retried in quick succession, so be careful with the configuration.
All the fields which you want to use and have configured as either key, message, message-id, correlation-id or additionalFields need to be added to
the SELECT clause of your query with the exact same name.
If a field is missing or incorrectly spelled, it will either be silently dropped or may default to another value.
-
Field Summary
Fields inherited from class AbstractJdbcListener
ADDITIONAL_QUERY_FIELDS_KEY, additionalFields, additionalFieldsList, correlationIdField, keyField, messageField, messageIdField, peekQuery, peekUntransacted, preparedPeekQuery, preparedSelectQuery, selectQuery, traceFields inherited from class JdbcFacade
logFields inherited from interface org.springframework.context.SmartLifecycle
DEFAULT_PHASE -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidafterMessageProcessed(PipeLineResult processResult, RawMessageWrapper<Serializable> rawMessage, PipeLineSession pipeLineSession) Called to perform actions (like committing or sending a reply) after a message has been processed by the Pipeline.voidConfigure this component.@Nullable RawMessageWrapper<Serializable> getRawMessage(@NonNull Map<String, Object> threadContext) Retrieves messages from queue or other channel, but does no processing on it.booleanvoidsetAfterProcessQuery(String afterProcessQuery) A SQL statement (UPDATEorDELETE) that can optionally be used to make sure theSELECTquery does not pick up the same row again.voidsetAfterSelectQuery(String afterSelectQuery) A SQL statement (UPDATEorDELETE) that can optionally be used to make sure theSELECTquery does not pick up the same row again.voidsetSelectQuery(String string) Methods inherited from class AbstractJdbcListener
addAdditionalValuesToMessageWrapper, closeThread, execute, extractMessage, extractRawMessage, getColumnValueOrDefault, getMessageKeyOrNull, openThread, setAdditionalFields, setCorrelationIdField, setKeyField, setMessageField, setMessageIdField, setPeekQuery, setPeekUntransactedMethods inherited from class JdbcFacade
convertQuery, getConnection, getConnectionWithTimeout, getDatasource, getDatasourceName, getDbmsSupport, getLogPrefix, getPassword, getPhysicalDestinationName, isRunning, setAuthAlias, setBlobCharset, setBlobsCompressed, setBlobSmartGet, setDatasourceName, setDbmsSupportFactory, setName, setPassword, setSqlDialect, setUsername, start, stop, withConnection, withConnectionMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.springframework.context.ApplicationContextAware
setApplicationContextMethods inherited from interface ConfigurableLifecycle
getPhase, isAutoStartup, isConfiguredMethods inherited from interface FrankElement
addConfigWarningMethods inherited from interface HasApplicationContext
getApplicationContext, getConfigurationClassLoaderMethods inherited from interface IListener
extractMessage, start, stopMethods inherited from interface IPeekableListener
isPeekUntransacted, setPeekUntransactedMethods inherited from interface IPullingListener
closeThread, openThreadMethods inherited from interface org.springframework.context.SmartLifecycle
isPauseable, stop
-
Constructor Details
-
StatelessJdbcListener
public StatelessJdbcListener()
-
-
Method Details
-
configure
Description copied from interface:IConfigurableConfigure this component.configure()is called once at startup of the framework in the configure method of the owner of thisIConfigurable. Purpose of this method is to check whether the static configuration of the object is correct. As much as possible class-instantiating should take place in theconfigure(), to improve performance.In the case of a container, this will propagate the configure signal to all components that apply.
- Specified by:
configurein interfaceIConfigurable- Overrides:
configurein classAbstractJdbcListener- Throws:
ConfigurationException- in case it was not able to configure the component.
-
hasRawMessageAvailable
- Specified by:
hasRawMessageAvailablein interfaceIPeekableListener<Serializable>- Overrides:
hasRawMessageAvailablein classAbstractJdbcListener- Throws:
ListenerException
-
getRawMessage
public @Nullable RawMessageWrapper<Serializable> getRawMessage(@NonNull Map<String, Object> threadContext) throws ListenerExceptionDescription copied from interface:IPullingListenerRetrieves messages from queue or other channel, but does no processing on it. Multiple objects may try to call this method at the same time, from different threads. Implementations of this method should therefore be thread-safe, orsynchronized.Any thread-specific properties should be stored in and retrieved from the threadContext.
If the returned object is an instance of
.MessageWrapperthen thewill not callinvalid reference
org.frankframework.receivers.Receiver#processRawMessage(IListener, RawMessageWrapper, PipeLineSession, boolean)IListener.extractMessage(RawMessageWrapper, Map)but directly access the enclosedMessageand theinvalid reference
RawMessageWrapper#getContext()- Specified by:
getRawMessagein interfaceIPullingListener<Serializable>- Throws:
ListenerException
-
afterMessageProcessed
public void afterMessageProcessed(PipeLineResult processResult, RawMessageWrapper<Serializable> rawMessage, PipeLineSession pipeLineSession) throws ListenerException Description copied from interface:IListenerCalled to perform actions (like committing or sending a reply) after a message has been processed by the Pipeline.- Specified by:
afterMessageProcessedin interfaceIListener<Serializable>- Throws:
ListenerException
-
setAfterSelectQuery
A SQL statement (UPDATEorDELETE) that can optionally be used to make sure theSELECTquery does not pick up the same row again. TheafterSelectQueryis executed immediately after theSELECTquery, before the pipeline is executed.
The query can have up to 3 parameters, values of which are taken in order from the fields mapped toAbstractJdbcListener.setKeyField(String),AbstractJdbcListener.setMessageIdField(String)andAbstractJdbcListener.setCorrelationIdField(String)in thesetSelectQuery(String).Deleting or updating the selected row immediately might reduce lock-contention on the table, however the row is not available anymore in the pipeline for other queries.
If the
Receiveris transactional, and the pipeline fails, the transaction is rolled back so theafterSelectQueryis rolled back. -
setAfterProcessQuery
A SQL statement (UPDATEorDELETE) that can optionally be used to make sure theSELECTquery does not pick up the same row again. TheafterProcessQueryis executed after the pipeline has finished.
The query can have up to 3 parameters, values of which are taken in order from the fields mapped toAbstractJdbcListener.setKeyField(String),AbstractJdbcListener.setMessageIdField(String)andAbstractJdbcListener.setCorrelationIdField(String)in thesetSelectQuery(String).Deleting or updating the selected row after processing in the pipeline is complete means the data of the row can be queried again in the pipeline, but also keeps the row locked for other queries outside the transaction.
The
afterProcessQueryis executed only when the pipeline has finished successfully.If the
Receiveris transactional, and the transaction is rolled back, theafterProcessQueryis rolled back if it was executed. -
setSelectQuery
- Overrides:
setSelectQueryin classAbstractJdbcListener
-