This is an automated email from the ASF dual-hosted git repository.
mattrpav pushed a commit to branch activemq-6.3.x
in repository https://gitbox.apache.org/repos/asf/activemq.git
The following commit(s) were added to refs/heads/activemq-6.3.x by this push:
new c39b17ad7e [#2431] Skip topic sendLock for non-persistent sends (#2476)
c39b17ad7e is described below
commit c39b17ad7ef3c067480c29ae22d172639009cb43
Author: Matt Pavlovich <[email protected]>
AuthorDate: Thu Aug 20 14:48:13 2026 -0500
[#2431] Skip topic sendLock for non-persistent sends (#2476)
(cherry picked from commit b2c57377cd408a80b74d44ec965ae116b72e9e78)
---
.../org/apache/activemq/broker/region/Topic.java | 31 +++++++++++++---------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git
a/activemq-broker/src/main/java/org/apache/activemq/broker/region/Topic.java
b/activemq-broker/src/main/java/org/apache/activemq/broker/region/Topic.java
index 714f95ef69..c79431daf2 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/region/Topic.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/region/Topic.java
@@ -530,10 +530,12 @@ public class Topic extends BaseDestination implements
Task {
* high contention (many concurrent producers with slow persistence or
* many subscribers).
*
- * The write lock is held only during persistence (to guarantee message
- * ordering via brokerSequenceId). Dispatch to subscribers and persistence
- * completion wait happen outside the lock, allowing concurrent dispatch
- * for messages from different producers.
+ * The lock is taken only on the persistent path, where it serializes the
+ * brokerSequenceId stamp together with the store add so the store write
+ * order matches the sequence order. Non-persistent sends stamp the
+ * sequence atomically and skip the lock entirely; dispatch to subscribers
+ * and the persistence completion wait happen outside the lock, allowing
+ * concurrent dispatch for messages from different producers.
*
* This is valid per Jakarta Messaging 3.1 Section 6.2.9: message ordering
* is guaranteed per-session/per-producer only. A JMS Session is not
@@ -549,12 +551,12 @@ public class Topic extends BaseDestination implements
Task {
final ConnectionContext context =
producerExchange.getConnectionContext();
Future<Object> result = null;
- // Write lock: serialize persistence for message ordering
- sendLock.lock();
- try {
-
message.getMessageId().setBrokerSequenceId(getDestinationSequenceId());
+ if (topicStore != null && message.isPersistent() &&
!canOptimizeOutPersistence()) {
+ // Serialize the sequence stamp with the store add for store
ordering
+ sendLock.lock();
+ try {
+
message.getMessageId().setBrokerSequenceId(getDestinationSequenceId());
- if (topicStore != null && message.isPersistent() &&
!canOptimizeOutPersistence()) {
if
(systemUsage.getStoreUsage().isFull(getStoreUsageHighWaterMark())) {
final String logMessage = "Persistent store is Full, " +
getStoreUsageHighWaterMark() + "% of "
+ systemUsage.getStoreUsage().getLimit() + ".
Stopping producer (" + message.getProducerId()
@@ -567,11 +569,16 @@ public class Topic extends BaseDestination implements
Task {
waitForSpace(context, producerExchange,
systemUsage.getStoreUsage(), getStoreUsageHighWaterMark(), logMessage);
}
result = topicStore.asyncAddTopicMessage(context, message,
isOptimizeStorage());
- }
+ message.incrementReferenceCount();
+ } finally {
+ sendLock.unlock();
+ }
+ } else {
+ // Non-persistent: the sequence stamp is atomic and JMS ordering is
+ // per-producer only, so independent producers need no
serialization.
+
message.getMessageId().setBrokerSequenceId(getDestinationSequenceId());
message.incrementReferenceCount();
- } finally {
- sendLock.unlock();
}
// Dispatch and persistence wait outside the lock — concurrent for
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact