If a XAResource does not support the read-only mode, the JTA
transaction manager will roll back the XAResource after a
read-only transaction ends, yes, but this is where JMS
implementations could step in and implement the read-only mode, so
that it doesn't have to roll back.
If JMS implementations move unacknowledged messages to a DLQ on a
transaction rollback, this would be unfortunate. IMO, messages
that are read via QueueBrowser should never be mutated or moved as
a result of a transaction commit/rollback, regardless of the
transaction read-only mode.
I don't know what you mean by a "mocking server", but with a
read-only transaction, the idea is that you can only read data
e.g. for monitoring UI purposes.
Regards,
Christian
Am 11.11.2025 um 16:37 schrieb Clebert
Suconic:
so, basically a read only transaction is a
transaction that you rollback (instead of commit) at the end,
and you should not perform any DLQs transfers (usually messaging
systems will move messages to DLQ after so many rollbacks).
you could also have the implementation to use dev/null
approach into producers and replace consumers by an equivalent
to browsing...
this would have some impact on the specification as I can
see.
Temporary queues should be disallowed as this is not really
a read only operation... or.. maybe we just make it a dumb
consumer?
The message system becomes like a mocking server under read
only operation?
On Mon, Nov 10, 2025 at
10:44 AM Christian Beikov via messaging-dev <messaging-dev@xxxxxxxxxxx>
wrote:
Hi Matt,
the main use case for read-only transactions is when you
only pull data without changing any state (no
insert/update/delete etc.) like any Web UI does. Knowing
that a transaction is read-only allows for certain
optimizations. Databases can avoid certain kinds of locks
or optimize the way such a transaction is handled.
Hibernate ORM for example can avoid dirty tracking of
entity objects. A datasource might hand out connections to
a read-only replica. I'm sure that once we have this
feature, we will come up with some more clever
optimizations.
I would say that the expectation on the JMS side is that
you implement this ExtendedXAResource interface, to ensure
such XASession objects that were put into read-only mode
throw errors if a mutation operation is invoked. This will
allow the JTA runtime to avoid calling rollback() in the
end. I don't know how rollback() is implemented, but I
would assume that a commit, even if empty, would perform
better generally.
Regards,
Christian
Am 10.11.2025 um 15:27 schrieb Matt Pavlovich:
Hi Christian-
Thank you for the clarification— curiously, it
would be helpful to me to have a concrete use-case to
gain a deeper understanding of how that would be used
in JDBC or object store. If you have a doc or link
that you could share, I would appreciate it!
Yes, currently the only area that the JMS spec
would be the JMS Browse. I do expect we’ll add some
acknowledgement modes to support streaming-style use
cases (ie NO_ACKNOWLEDGEMENT) to consumer, but there
is nothing defined today.
Since a JMS Browse is read-only in any case, I’m
not sure what change would be expected if the
transaction is in a ‘readOnly’ configuration vs a
non-readOnly configuration.
In JMS, XA comes in at the ConnectionFactory and
ultimately a XASession is created. There would be
some weird things to sort out, since an XASession is
the junction across Producer, Consumer and Browser
sharing state (ie.. consume a message and produce
back to another queue on the same broker in one
transaction). Something along the lines of— if the
XAResource is configured with ‘readOnly’ flag,
creating a producer or consumer off of that
XASession should throw an unsupported exception to
signal to the developer that they have an
inconsistent configuration.
roughly speaking, the intent of "read-only"
is that operations within such a transaction
may not change data in any form.
From a Jakarta Messaging perspective I
would say that the only reasonable usage of
a read-only transaction I can imagine is
with the QueueBrowser when messages are just
viewed, but never altered, removed or moved.
Is it possible/sensible to have a
MessageConsumer that is read-only i.e. never
changes the state of messages but just
browses through them?Unless you think it is
useful, I think we can limit the discussion
to QueueBrowser.
The read-only nature does not impose any
other semantics. So any concerns about race
conditions, or more broadly speaking
transaction isolation, are irrelevant.
Regards,
Christian
Am 08.11.2025 um 20:36 schrieb Matt
Pavlovich via messaging-dev:
Hi Scott-
What does ‘readOnly’ mean in this
context? More specifically— Do you have a
concrete use-case that would involve
messaging to provide additional context?
Questions:
Is the intent to be ‘read-only’ or ’not
impacting data change anywhere’?
What would be the expected behavior if
the first message on the queue was
malformed? Would the consumer reject the
message (then it would be the same message
the next time through) or move the message
to a dead-letter-queue and try to see if
the next message was valid?
Is there an expectation that no state
changes (across all resources) between
‘read’ message will be there if a
subsequent ‘write’ transaction occurs
after the readOnly completes? (ie timing /
race condition)
From the messaging perspective,
‘readOnly’ could be interpreted different
ways:.
1. A messaging consumer is read-only
from the perspective of the
queue-to-the-application.
- or -
2. A messaging consumer could be
considered a data changing operation from
the perspective of the queue-only (the
queue now has less message(s)).
- or -
3. Browse message(s) in a
transaction— no guarantee the they will
be there if the app tries to immediately
open a consumer after browsing, since
another consumer may have processed them
in the time between (aka race
condition).
The Jakarta EE 12
Platform will include
Jakarta Transactions 2.1
which includes readOnly
hint added to the
`jakarta.transaction.Transactional`
annotation [1][2] which
users.
I'm going to paste some
specification text from
the [3] pull request that
describes the expected
action to be taken if
read-only mode is enabled
for a XAResource:
"
If the current
transaction is in the
read-only mode, the
transaction manager tries
to put the enlisted
resource in the read-only
mode by invoking the
`ExtendedXAResource#setReadOnly`
method if it implements
the `ExtendedXAResource`
interface. If the
`ExtendedXAResource`
cannot be put into
read-only mode or the
`XAResource` does not
implement the
`ExtendedXAResource`
interface, the transaction
manager must roll back the
`XAResource` at
transaction commit.
"
Could the Messaging
specification team please
respond with feedback on
this new read-only feature
and whether the EE 12 Platform
specification text
should mention any
Messaging features that
are not expected to
support read-only
transactions? If yes,
which Messaging features
will not work with
read-only transactions?
Also if yes, should we
open a Messaging (4.0)
issue to add changes to
support read-only
transactions?
For example, could QueueBrowser always
work in an active transaction
with a (read-only mode
enabled) ExtendedXAResource?
More specifically could a
Messaging implementation
expect to update the database
during the queue browse
operation? I find it unlikely
that any implementation would
update the (queue) database
during a browse operation but
want to hear your feedback on
whether that would be
allowed? One possible reason
for updating the application
database is to save
QueueBrowser statistics to the
application database.
Perhaps we can come up with
generic EE 12 Platform text to
describe that any database
update performed against a
read-only Resource will not be
saved or something like that
to cover ^ and operations like
that. Still, I'we are looking
to better understand the
possible cases and what can be
expected to work/not work.
Thanks,
Scott
Note that there is a
Connectors issue [4] open
as well.