A no-argument QueueChannel is effectively unbounded in memory; a bounded queue still disappears when the process stops.
Spring Integration queue: bound memory and choose a real message store
Capacity is not durability
An intake bridge that creates QueueChannel(64) limits local backlog, but message 65 can block its sender until a receiver frees space. A no-argument QueueChannel permits an Integer.MAX_VALUE capacity and can drive the heap into failure long before that numerical limit. Neither form survives a JVM exit. An asynchronous handoff is only a thread decision until a durable store is introduced.
Use the store built for channels
For persistent channel traffic, JdbcChannelMessageStore is designed for the channel queue use case. Provision its database tables, choose a unique region or group identifier, and configure a transactional poller if removal must roll back when the handler fails. A broker-backed channel is another option, with different acknowledgment behavior. The poller boundary is where a stored message becomes processing work.
Kill the process in a test
Publish 37 unique parcel IDs, stop the worker after a known number of commits, restart from the same store, and reconcile accepted, processed and pending IDs. A memory-only test cannot prove that work survives a crash. The sample below is only the bounded in-memory choice; a durable deployment needs explicit JDBC or broker wiring and an integration test.
Implementation sketch
@Bean
QueueChannel localParcelBuffer() {
return new QueueChannel(64);
}Cost and verification
A bounded memory queue caps heap use but can backpressure callers. A JDBC store adds database writes, indexes and retention work; measure poll latency and disk growth under the expected backlog.
Common Mistakes
- Do not call a bounded in-memory QueueChannel durable.
- Do not leave QueueChannel at its no-argument capacity on an untrusted input path.
- Do not assume a persistent queue removes messages transactionally without checking the poller and handler boundary.
Read next
Spring Integration poller: include receive and handler in the failure boundary, Spring Integration DirectChannel versus ExecutorChannel: where the transaction stops, Spring worker shutdown: release admission before a lease expires, Spring outbox claims: lease expiry and token-fenced acknowledgement.
