Class JdbcChannelMessageStore
- All Implemented Interfaces:
- InitializingBean,- Lifecycle,- Phased,- SmartLifecycle,- BasicMessageGroupStore,- ChannelMessageStore,- PriorityCapableChannelMessageStore
 Channel-specific implementation of
 BasicMessageGroupStore using a relational
 database via JDBC.
 
This message store shall be used for message channels only.
 As such, the JdbcChannelMessageStore uses database specific SQL queries.
 
 Contrary to the JdbcMessageStore, this implementation uses a single database table,
 optimized to operate like a queue.
 The SQL scripts for creating the table are packaged
 under org/springframework/integration/jdbc/schema-*.sql,
 where * denotes the target database type.
 
 This class implements SmartLifecycle and calls getMessageGroupCount()
 on start() to check if required table is present in DB.
 The application context will fail to start if the table is not present.
 This check can be disabled via setCheckDatabaseOnStart(boolean).
- Since:
- 2.2
- Author:
- Gunnar Hillert, Artem Bilan, Gary Russell, Meherzad Lahewala, Trung Pham, Johannes Edmeier, Ngoc Nhan
- 
Field SummaryFieldsModifier and TypeFieldDescriptionstatic final StringDefault region property, used to partition the message store.static final StringDefault value for the table prefix property.Fields inherited from interface org.springframework.context.SmartLifecycleDEFAULT_PHASE
- 
Constructor SummaryConstructorsConstructorDescriptionConvenient constructor for configuration use.JdbcChannelMessageStore(DataSource dataSource) Create aMessageStorewith all mandatory properties.
- 
Method SummaryModifier and TypeMethodDescriptionvoidaddAllowedPatterns(String... patterns) Add patterns for packages/classes that are allowed to be deserialized.addMessageToGroup(Object groupId, Message<?> message) Store a message in the database.voidCheck mandatory properties (DataSourceandsetChannelMessageStoreQueryProvider(ChannelMessageStoreQueryProvider)).protected Message<?> doPollForMessage(String groupIdKey) This method executes a call to the DB to get the oldest Message in the MessageGroup which in the context of theJdbcChannelMessageStoremeans the channel identifier.getMessageGroup(Object groupId) Not fully used.intReturn the number of message groups in the store for configured region.protected MessageGroupFactoryReturn theMessageGroupFactory.protected StringgetQuery(org.springframework.integration.jdbc.store.JdbcChannelMessageStore.Query queryName, Supplier<String> queryProvider) Replace patterns in the input to produce a valid SQL query.Returns the current region that was set orDEFAULT_REGION, which is the default.intReturn the size of the Message Id Cache, which caches Message Ids for those messages that are currently being processed.booleanbooleanbooleanintmessageGroupSize(Object groupId) Return the number of messages persisted for the specified channel id (groupId) and the specified region (setRegion(String)).Message<?> pollMessageFromGroup(Object groupId) Poll the database for a new message that is persisted for the given group id which represents the channel identifier.voidremoveFromIdCache(String messageId) Remove a Message Id from the idCache.voidremoveMessageGroup(Object groupId) Remove the message group with this id.voidsetChannelMessageStoreQueryProvider(ChannelMessageStoreQueryProvider channelMessageStoreQueryProvider) Set the database specificChannelMessageStoreQueryProviderto use.voidsetCheckDatabaseOnStart(boolean checkDatabaseOnStart) The flag to perform a database check query on start or not.voidsetDataSource(DataSource dataSource) The JDBCDataSourceto use when interacting with the database.voidsetDeserializer(Deserializer<? extends Message<?>> deserializer) A converter for deserializing byte arrays to messages.voidsetJdbcTemplate(JdbcTemplate jdbcTemplate) TheJdbcOperationsto use when interacting with the database.voidsetMessageGroupFactory(MessageGroupFactory messageGroupFactory) Specify theMessageGroupFactoryto createMessageGroupobject where it is necessary.voidsetMessageRowMapper(MessageRowMapper messageRowMapper) Allow for passing in a customMessageRowMapper.voidsetPreparedStatementSetter(ChannelMessageStorePreparedStatementSetter preparedStatementSetter) Set aChannelMessageStorePreparedStatementSetterto insert message into the database.voidsetPriorityEnabled(boolean priorityEnabled) Enable a priority handling in this store.voidA unique grouping identifier for all messages persisted with this store.voidsetSerializer(Serializer<? super Message<?>> serializer) A converter for serializing messages to byte arrays for storage.voidsetTablePrefix(String tablePrefix) Public setter for the table prefix property.voidsetUsingIdCache(boolean usingIdCache) Consider using this property when polling the database transactionally using multiple parallel threads, meaning when the configured poller is configured using a task executor.voidstart()voidstop()Methods inherited from class java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.springframework.context.SmartLifecyclegetPhase, stop
- 
Field Details- 
DEFAULT_REGIONDefault region property, used to partition the message store. For example, a separate Spring Integration application with overlapping channel names may use the same message store by providing a distinct region name.- See Also:
 
- 
DEFAULT_TABLE_PREFIXDefault value for the table prefix property.- See Also:
 
 
- 
- 
Constructor Details- 
JdbcChannelMessageStorepublic JdbcChannelMessageStore()Convenient constructor for configuration use.
- 
JdbcChannelMessageStoreCreate aMessageStorewith all mandatory properties. The passed-inDataSourceis used to instantiate aJdbcTemplatewithJdbcTemplate.setFetchSize(int)set to1and withJdbcTemplate.setMaxRows(int)set to1.- Parameters:
- dataSource- a- DataSource
 
 
- 
- 
Method Details- 
setDataSourceThe JDBCDataSourceto use when interacting with the database. The passed-inDataSourceis used to instantiate aJdbcTemplatewithJdbcTemplate.setFetchSize(int)set to1and withJdbcTemplate.setMaxRows(int)set to1.- Parameters:
- dataSource- a- DataSource
 
- 
setDeserializerA converter for deserializing byte arrays to messages.- Parameters:
- deserializer- the deserializer to set
 
- 
addAllowedPatternsAdd patterns for packages/classes that are allowed to be deserialized. A class can be fully qualified or a wildcard '*' is allowed at the beginning or end of the class name. Examples:com.foo.*,*.MyClass.- Parameters:
- patterns- the patterns.
- Since:
- 5.4
 
- 
setJdbcTemplateTheJdbcOperationsto use when interacting with the database. Either this property can be set or thedataSource. Please consider passing in aJdbcTemplatewith a fetchSize property of 1. This is particularly important for Oracle to ensure First In, First Out (FIFO) message retrieval characteristics.- Parameters:
- jdbcTemplate- a- JdbcOperations
 
- 
setMessageRowMapperAllow for passing in a customMessageRowMapper. TheMessageRowMapperis used to convert the selected database row representing the persisted message into the actualMessageobject.- Parameters:
- messageRowMapper- Must not be null
 
- 
setPreparedStatementSetterpublic void setPreparedStatementSetter(ChannelMessageStorePreparedStatementSetter preparedStatementSetter) Set aChannelMessageStorePreparedStatementSetterto insert message into the database.- Parameters:
- preparedStatementSetter-- ChannelMessageStorePreparedStatementSetterto use. Must not be null
- Since:
- 5.0
 
- 
setChannelMessageStoreQueryProviderpublic void setChannelMessageStoreQueryProvider(ChannelMessageStoreQueryProvider channelMessageStoreQueryProvider) Set the database specificChannelMessageStoreQueryProviderto use. TheJdbcChannelMessageStoreprovides the SQL queries to retrieve messages from the database. See the JavaDocsChannelMessageStoreQueryProvider(all known implementing classes) to see those implementations provided by the framework.You can provide your own query implementations, if you need to support additional databases and/or need to fine-tune the queries for your requirements. - Parameters:
- channelMessageStoreQueryProvider- Must not be null.
 
- 
setRegionA unique grouping identifier for all messages persisted with this store. Using multiple regions allows the store to be partitioned (if necessary) for different purposes. Defaults toDEFAULT_REGION.- Parameters:
- region- the region name to set
 
- 
getRegionReturns the current region that was set orDEFAULT_REGION, which is the default.- Returns:
- the set region name
- Since:
- 6.0
 
- 
setSerializerA converter for serializing messages to byte arrays for storage.- Parameters:
- serializer- The serializer to set
 
- 
setTablePrefixPublic setter for the table prefix property. This will be prefixed to all the table names before queries are executed. Defaults toDEFAULT_TABLE_PREFIX.- Parameters:
- tablePrefix- the tablePrefix to set
 
- 
setUsingIdCachepublic void setUsingIdCache(boolean usingIdCache) Consider using this property when polling the database transactionally using multiple parallel threads, meaning when the configured poller is configured using a task executor. The issue is that the pollMessageFromGroup(Object)looks for the oldest entry for a giving channel (groupKey) and region (setRegion(String)). If you do that with multiple threads and you are using transactions, other threads may be waiting for that same locked row.If using the provided OracleChannelMessageStoreQueryProvider, don't setusingIdCacheto true, as the Oracle query will ignore locked rows.Using the id cache, the JdbcChannelMessageStorewill store each message id in an in-memory collection for the duration of processing. With that, any polling threads will explicitly exclude those messages from being polled.For this to work, you must setup the corresponding TransactionSynchronizationFactory:
 This<int:transaction-synchronization-factory id="syncFactory"> <int:after-commit expression="@jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" /> <int:after-rollback expression="@jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" /> </int:transaction-synchronization-factory>TransactionSynchronizationFactoryis then referenced in the transaction configuration of the poller:<int:poller fixed-delay="300" receive-timeout="500" max-messages-per-poll="1" task-executor="pool"> <int:transactional propagation="REQUIRED" synchronization-factory="syncFactory" isolation="READ_COMMITTED" transaction-manager="transactionManager" /> </int:poller>- Parameters:
- usingIdCache- When- truethe id cache will be used.
 
- 
setPriorityEnabledpublic void setPriorityEnabled(boolean priorityEnabled) Enable a priority handling in this store.- Parameters:
- priorityEnabled- the priority handling enabled or not.
 
- 
isPriorityEnabledpublic boolean isPriorityEnabled()- Specified by:
- isPriorityEnabledin interface- PriorityCapableChannelMessageStore
- Returns:
- true if message priority is enabled in this channel message store.
 
- 
setMessageGroupFactorySpecify theMessageGroupFactoryto createMessageGroupobject where it is necessary. Defaults toSimpleMessageGroupFactory.- Parameters:
- messageGroupFactory- the- MessageGroupFactoryto use.
- Since:
- 4.3
 
- 
getMessageGroupFactoryReturn theMessageGroupFactory.- Returns:
- the MessageGroupFactory
 
- 
afterPropertiesSetpublic void afterPropertiesSet()Check mandatory properties (DataSourceandsetChannelMessageStoreQueryProvider(ChannelMessageStoreQueryProvider)). If noMessageRowMapperandChannelMessageStorePreparedStatementSetterwas explicitly set usingsetMessageRowMapper(MessageRowMapper)andsetPreparedStatementSetter(ChannelMessageStorePreparedStatementSetter)respectively, the defaultMessageRowMapperandChannelMessageStorePreparedStatementSetterwill be instantiated using the specifieddeserializer. Also, if the jdbcTemplate's fetchSize property (JdbcTemplate.getFetchSize()) is not 1, a warning will be logged. When using theJdbcChannelMessageStorewith Oracle, the fetchSize value of 1 is needed to ensure FIFO characteristics of polled messages. Please see the OracleChannelMessageStoreQueryProviderfor more details.- Specified by:
- afterPropertiesSetin interface- InitializingBean
 
- 
setCheckDatabaseOnStartpublic void setCheckDatabaseOnStart(boolean checkDatabaseOnStart) The flag to perform a database check query on start or not.- Parameters:
- checkDatabaseOnStart- false to not perform the database check.
- Since:
- 6.2
 
- 
isAutoStartuppublic boolean isAutoStartup()- Specified by:
- isAutoStartupin interface- SmartLifecycle
 
- 
start
- 
stop
- 
isRunning
- 
addMessageToGroupStore a message in the database. The groupId identifies the channel for which the message is to be stored. Keep in mind that the actual groupId (Channel Identifier) is converted to a String-based UUID identifier.- Specified by:
- addMessageToGroupin interface- BasicMessageGroupStore
- Parameters:
- groupId- the group id to store the message under
- message- a message
- Returns:
- The message group.
 
- 
getMessageGroupNot fully used. Only wraps the provided group id.- Specified by:
- getMessageGroupin interface- BasicMessageGroupStore
- Parameters:
- groupId- The group identifier.
- Returns:
- A group of messages, empty if none exists for this key.
 
- 
getMessageGroupCountReturn the number of message groups in the store for configured region.- Returns:
- The message group count.
 
- 
getQueryprotected String getQuery(org.springframework.integration.jdbc.store.JdbcChannelMessageStore.Query queryName, Supplier<String> queryProvider) Replace patterns in the input to produce a valid SQL query. This implementation lazily initializes a simple map-based cache, only replacing the table prefix on the first access to a named query. Subsequent accesses will be resolved from the cache.- Parameters:
- queryName- The- JdbcChannelMessageStore.Queryto be transformed.
- queryProvider- a supplier to provide the query template.
- Returns:
- A transformed query with replacements.
 
- 
messageGroupSizeReturn the number of messages persisted for the specified channel id (groupId) and the specified region (setRegion(String)).- Specified by:
- messageGroupSizein interface- BasicMessageGroupStore
- Parameters:
- groupId- The group identifier.
- Returns:
- The message group size.
 
- 
removeMessageGroupDescription copied from interface:BasicMessageGroupStoreRemove the message group with this id.- Specified by:
- removeMessageGroupin interface- BasicMessageGroupStore
- Parameters:
- groupId- The id of the group to remove.
 
- 
pollMessageFromGroupPoll the database for a new message that is persisted for the given group id which represents the channel identifier.- Specified by:
- pollMessageFromGroupin interface- BasicMessageGroupStore
- Parameters:
- groupId- The group identifier.
- Returns:
- The message.
 
- 
doPollForMessageThis method executes a call to the DB to get the oldest Message in the MessageGroup which in the context of theJdbcChannelMessageStoremeans the channel identifier.- Parameters:
- groupIdKey- String representation of message group (Channel) ID
- Returns:
- a message; could be null if query produced no Messages
 
- 
removeFromIdCacheRemove a Message Id from the idCache. Should be used in conjunction with the Spring Integration Transaction Synchronization feature to remove a message from the Message Id cache once a transaction either succeeded or rolled back. Only applicable ifsetUsingIdCache(boolean)is set totrue.- Parameters:
- messageId- The message identifier.
 
- 
getSizeOfIdCacheReturn the size of the Message Id Cache, which caches Message Ids for those messages that are currently being processed.- Returns:
- The size of the Message Id Cache
 
 
-