You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Maciej Szefler <mb...@intalio.com> on 2007/09/04 16:16:48 UTC

Transactional JMS.

Hi,

I've been unable to find anything on the topic in Nabble, so I thought I'd
ping you all, and Asankha in particular regarding transactions in the JMS
transport implementation.
In ODE we'd like to be able to consume/send messages through AXIS' JMS
transport. That in itself is not a problem. However, we'd like the
send/receive to be in enrolled in a JTA transaction. Any pointers on how
this can be done?

-Maciej

Re: Transactional JMS.

Posted by Rajith Attapattu <ra...@gmail.com>.
Hi maciej,

comments inline.

On 9/5/07, Maciej Szefler <mb...@intalio.com> wrote:
>
> Hi Rajith,
>
> See my  commments inline.
>
> On 9/4/07, Rajith Attapattu < rajith77@gmail.com> wrote:
> >
> >
> >
> > Sorry if I was not clear enough. When I said session per service, I
> > meant session per service instance (where it make sense). So no need to
> > serialize access.
> > Ex. If you have a service with scope='soap-session' and there are two
> > clients talking to it, then you would have two instances of the service and
> > would be using two JMS sessions (or two XA sessions). So each web service
> > instance can run transactions independently of the other.
> >
> Ok,  I think we are on same page.
>
>
> > In the use case where services with scope='request' sharing sessions
> > underneath, a given JMS session will only be used by one and only one
> > service instance at a given time. (This will be tricky to implement, and
> > only be worth if there is a high traffic scenario).
> >
> > Going direct, we still have a problem with receving messages. As far I
> > > know, it is not possible to do a JTA receive using the async MessageListener
> > > interface. One would need to either poll, or  use the MessageConsumer
> > > interfaces.
> >
> >
> > Async or sync message receive is orthogonal to the transactions. Can you
> > elaborate a bit more
> >
>
> Sure... When receiving messages when not using JTA, you can simply set up
> a MessageListener via the MessageConsumer (as is the current practice in
> AXIS). In the JTA case there is the compilication that the JTA transaction
> needs to be started before the message is consumed. So you can do something
> like this (ugly):
>
> jta.begin();
> session.receive(timeout);
> if (timeout)
>    jta.rollback();
> else
>   do some stuff...
>   jta.commit();
>

I get what you mean. You need your service invocation (jms message
consumption) as part of a transaction.
How about if we call xaSession.getXAResource().start() as soon as we create
the session? then every message it consumes and sends will be within that
transaction until it commits or rolls it back.

However transactions will have an impact on the client who does the
invocation. If rollback happens. Any messages u consume will be enqueued
again by the provider. What are we going to do with that message?
Also how are we going to notify the client? In that case are we supposed to
send the client a seperate axis2 fault?

Actually there a few things to consider and I am not sure I have figured out
all those complications.
Maybe we should rethink about implementing transactions in the JMS transport
for axis2 as it will complicate the interactions.

Actually can you explain your use case a bit more? Can you not use
WS-Transactions? Perhaps there is a simple way to solve your problem

Regards,

Rajith

Alternatively you can use the ConnectionConsumer / ServerSessionPool
> interfaces which allow one to start a JTA tx before the message is actually
> consumed. This is a bit complicated, and also is an "optional" feature.
>
> Or you can use MessageConsumer and try to enroll the XASession in the
> transaction from the MessageListener.onMessage method. I do not believe
> this to be entirely legal as far as the spec is concerned, but I hear it
> works on some JMS providers.
>
>
>  In either case there is the issue of who begins and commits the JTA
> > > transaction (AXIS2 or the service), and if its the service, it is not clear
> > > how that interaction would look.
> > >
> > I'm more inclined toward an  MDB-like model, where AXIS starts the TX,
> > > calls the service, and then barring some indication to the contrary,
> > > attempts to commit.
> >
> >
> > IMO Axis2 should not commit or rollback automatically. Commits or
> > rollbacks can happen based on business decisions as well as system errors.
> > And in the case of a distributed transaction the decision to commit or
> > rollback will come from the distributed transaction manager.
> >
>
> I agree in principle, but to do that, what you'd really need is to
> decouple the notification that a message is available, from the act of
> consuming the message.Something along these lines:
> MyAxisService.onMessageReceived () {
>     jta.begin();
>     MessageContext ctx = consumeMessage() // message is consumed in the
> JTA TX
>     this.doServiceWork();
>     jta.commit ();
> }
>
> Getting something like that may be difficult (per my previous comments
> regarding JTA / session enrollment).
>
> -maciej
>
>  If there are any system(axis2) hiccups then axis2 will/should always
> > throw a fault and the service author will be notified instead of axis2 doing
> > rollback.
> > In the case of a local transaction the service author may rollback and
> > in a distributed transaction the XA resource (XA Session) will throw an
> > exception in the prepare method and the the transaction manager will call
> > rollback.
> >
> > -mbs
> > >
> > > On 9/4/07, Rajith Attapattu <ra...@gmail.com> wrote:
> > > >
> > > > Maciej,
> > > >
> > > > Currently there are a few problems with doing this. Lets identify
> > > > the issues
> > > > a) We create a new connection for each invocation (sending messages)
> > > > b) Hence we create a new session for each invocation.
> > > > c) When creating a session for receiving as well as sending
> > > > transacted is set to true - no way to configure this.
> > > > d) We currently don't expose the session outside for both transport
> > > > sender/receiver, hence you cannot call commit or rollback on it.
> > > > e) Since u are using JTA I assume it's a distributed transaction. So
> > > > we need to create an XASession instead of a normal session.
> > > >
> > > > This can be done and here are some ideas. I spoke with Asankha
> > > > briefly on this topic once.
> > > >
> > > > a) Asankha pointed out a new connection is created for each
> > > > invocation as each service could have different connection params.
> > > > (different provider, username,..etc)
> > > > The downside of this is that creating new connections is an
> > > > expensive operation. Especially if the same service sends frequent messages
> > > > it will keep recreating connections. We should make this behaviour
> > > > configurable.
> > > > I would like if we could reuse connections where we can. Also in
> > > > most cases a deployment would use a single provider and we can definitely
> > > > optimize for this case.
> > > > For this case we can get away with a single connection per axis2
> > > > instance and session per service (one for sending and one for listening).
> > > >
> > > > If we can name connections then we could reuse them when defining
> > > > services. This way we can check if an existing connection by that name
> > > > exists and reuse it, if not create one.
> > > >
> > > > When we reuse connections there will be keep alive issues. Most
> > > > providers have convenient and cheap ways of sending ping/pongs to keep the
> > > > connection alive.
> > > > So in a case where the service sends messages frequently this will
> > > > help. If the service sends messages rarely and the cost of keep alive is
> > > > greater than the occasional connection creation then the user can disable
> > > > the reuse option.
> > > >
> > > > b) Creating a new session for each invocation is not optimal. Since
> > > > the context hierarchy determines the scope of services and is independent of
> > > > the transport session it's ok to reuse a JMS session underneath where ever
> > > > it makes sense. If we introduce some thing similar to
> > > > scope="transport-session" in HTTP for JMS, then we can allow users to
> > > > directly use the underlying JMS transport similar to the way HTTP session is
> > > > used.
> > > >
> > > > c) We can make the transacted property configurable. By default it
> > > > will be false.
> > > > <http://?auth=DQAAAHcAAABRNsIxA9tiVL3uczzey-x8FmU4gCUONPWKQAnlvhxhlFsCgDWBe2vo5cADP4RK1n0C-wf599ttpb3KuVGEQ1juQ4qqo7J7q47y0qAH12dW5DBAfbWjNSE-kzSN7uva1VddYFgwsvDPJHEKd2xLegIlVRPoMUsCpGd8rccaRUkjtg&shva=1>
> > > > Ex: <parameter name="transport.jms.SessionTransacted
> > > > ">true</parameter>
> > > >
> > > > d) We need to expose the JMS session. Can we put the JMS session
> > > > somewhere in the context hierarchy?
> > > > I also see a getSessionContext in TransportListener interface,
> > > > However SessionContext is written with HTTP in mind and is not generic
> > > > enough.
> > > > If we put it in the content hierarchy then the service author can
> > > > retrieve it and call commit, rollback etc.
> > > >
> > > > e) We can create an XASession  instead of a normal session based on
> > > > configuration, provided the JMS provider supports it.
> > > > Ex. <parameter name="transport.jms.XASession">true</parameter>
> > > >
> > > > Comments are very much appreciated.
> > > >
> > > > Regards,
> > > >
> > > > Rajith
> > > >
> > > > On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > I've been unable to find anything on the topic in Nabble, so I
> > > > > thought I'd ping you all, and Asankha in particular regarding transactions
> > > > > in the JMS transport implementation.
> > > > > In ODE we'd like to be able to consume/send messages through AXIS'
> > > > > JMS transport. That in itself is not a problem. However, we'd like the
> > > > > send/receive to be in enrolled in a JTA transaction. Any pointers on how
> > > > > this can be done?
> > > > >
> > > > > -Maciej
> > > > >
> > > >
> > > >
> > >
> >
>

Re: Transactional JMS.

Posted by Maciej Szefler <mb...@intalio.com>.
Hi Rajith,

See my  commments inline.

On 9/4/07, Rajith Attapattu <ra...@gmail.com> wrote:
>
>
>
> Sorry if I was not clear enough. When I said session per service, I meant
> session per service instance (where it make sense). So no need to serialize
> access.
> Ex. If you have a service with scope='soap-session' and there are two
> clients talking to it, then you would have two instances of the service and
> would be using two JMS sessions (or two XA sessions). So each web service
> instance can run transactions independently of the other.
>
Ok,  I think we are on same page.


> In the use case where services with scope='request' sharing sessions
> underneath, a given JMS session will only be used by one and only one
> service instance at a given time. (This will be tricky to implement, and
> only be worth if there is a high traffic scenario).
>
> Going direct, we still have a problem with receving messages. As far I
> > know, it is not possible to do a JTA receive using the async MessageListener
> > interface. One would need to either poll, or  use the MessageConsumer
> > interfaces.
>
>
> Async or sync message receive is orthogonal to the transactions. Can you
> elaborate a bit more
>

Sure... When receiving messages when not using JTA, you can simply set up a
MessageListener via the MessageConsumer (as is the current practice in
AXIS). In the JTA case there is the compilication that the JTA transaction
needs to be started before the message is consumed. So you can do something
like this (ugly):

jta.begin();
session.receive(timeout);
if (timeout)
   jta.rollback();
else
  do some stuff...
  jta.commit();

Alternatively you can use the ConnectionConsumer / ServerSessionPool
interfaces which allow one to start a JTA tx before the message is actually
consumed. This is a bit complicated, and also is an "optional" feature.

Or you can use MessageConsumer and try to enroll the XASession in the
transaction from the MessageListener.onMessage method. I do not believe this
to be entirely legal as far as the spec is concerned, but I hear it works on
some JMS providers.


 In either case there is the issue of who begins and commits the JTA
> > transaction (AXIS2 or the service), and if its the service, it is not clear
> > how that interaction would look.
> >
> I'm more inclined toward an  MDB-like model, where AXIS starts the TX,
> > calls the service, and then barring some indication to the contrary,
> > attempts to commit.
>
>
> IMO Axis2 should not commit or rollback automatically. Commits or
> rollbacks can happen based on business decisions as well as system errors.
> And in the case of a distributed transaction the decision to commit or
> rollback will come from the distributed transaction manager.
>

I agree in principle, but to do that, what you'd really need is to decouple
the notification that a message is available, from the act of consuming the
message.Something along these lines:
MyAxisService.onMessageReceived () {
    jta.begin();
    MessageContext ctx = consumeMessage() // message is consumed in the JTA
TX
    this.doServiceWork();
    jta.commit();
}

Getting something like that may be difficult (per my previous comments
regarding JTA / session enrollment).

-maciej

If there are any system(axis2) hiccups then axis2 will/should always throw a
> fault and the service author will be notified instead of axis2 doing
> rollback.
> In the case of a local transaction the service author may rollback and in
> a distributed transaction the XA resource (XA Session) will throw an
> exception in the prepare method and the the transaction manager will call
> rollback.
>
> -mbs
> >
> > On 9/4/07, Rajith Attapattu <ra...@gmail.com> wrote:
> > >
> > > Maciej,
> > >
> > > Currently there are a few problems with doing this. Lets identify the
> > > issues
> > > a) We create a new connection for each invocation (sending messages)
> > > b) Hence we create a new session for each invocation.
> > > c) When creating a session for receiving as well as sending transacted
> > > is set to true - no way to configure this.
> > > d) We currently don't expose the session outside for both transport
> > > sender/receiver, hence you cannot call commit or rollback on it.
> > > e) Since u are using JTA I assume it's a distributed transaction. So
> > > we need to create an XASession instead of a normal session.
> > >
> > > This can be done and here are some ideas. I spoke with Asankha briefly
> > > on this topic once.
> > >
> > > a) Asankha pointed out a new connection is created for each invocation
> > > as each service could have different connection params. (different provider,
> > > username,..etc)
> > > The downside of this is that creating new connections is an expensive
> > > operation. Especially if the same service sends frequent messages it will
> > > keep recreating connections. We should make this behaviour configurable.
> > > I would like if we could reuse connections where we can. Also in most
> > > cases a deployment would use a single provider and we can definitely
> > > optimize for this case.
> > > For this case we can get away with a single connection per axis2
> > > instance and session per service (one for sending and one for listening).
> > >
> > > If we can name connections then we could reuse them when defining
> > > services. This way we can check if an existing connection by that name
> > > exists and reuse it, if not create one.
> > >
> > > When we reuse connections there will be keep alive issues. Most
> > > providers have convenient and cheap ways of sending ping/pongs to keep the
> > > connection alive.
> > > So in a case where the service sends messages frequently this will
> > > help. If the service sends messages rarely and the cost of keep alive is
> > > greater than the occasional connection creation then the user can disable
> > > the reuse option.
> > >
> > > b) Creating a new session for each invocation is not optimal. Since
> > > the context hierarchy determines the scope of services and is independent of
> > > the transport session it's ok to reuse a JMS session underneath where ever
> > > it makes sense. If we introduce some thing similar to
> > > scope="transport-session" in HTTP for JMS, then we can allow users to
> > > directly use the underlying JMS transport similar to the way HTTP session is
> > > used.
> > >
> > > c) We can make the transacted property configurable. By default it
> > > will be false.
> > > <http://?auth=DQAAAHcAAABRNsIxA9tiVL3uczzey-x8FmU4gCUONPWKQAnlvhxhlFsCgDWBe2vo5cADP4RK1n0C-wf599ttpb3KuVGEQ1juQ4qqo7J7q47y0qAH12dW5DBAfbWjNSE-kzSN7uva1VddYFgwsvDPJHEKd2xLegIlVRPoMUsCpGd8rccaRUkjtg&shva=1>
> > > Ex: <parameter name="transport.jms.SessionTransacted">true</parameter>
> > >
> > > d) We need to expose the JMS session. Can we put the JMS session
> > > somewhere in the context hierarchy?
> > > I also see a getSessionContext in TransportListener interface, However
> > > SessionContext is written with HTTP in mind and is not generic enough.
> > > If we put it in the content hierarchy then the service author can
> > > retrieve it and call commit, rollback etc.
> > >
> > > e) We can create an XASession  instead of a normal session based on
> > > configuration, provided the JMS provider supports it.
> > > Ex. <parameter name="transport.jms.XASession">true</parameter>
> > >
> > > Comments are very much appreciated.
> > >
> > > Regards,
> > >
> > > Rajith
> > >
> > > On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > I've been unable to find anything on the topic in Nabble, so I
> > > > thought I'd ping you all, and Asankha in particular regarding transactions
> > > > in the JMS transport implementation.
> > > > In ODE we'd like to be able to consume/send messages through AXIS'
> > > > JMS transport. That in itself is not a problem. However, we'd like the
> > > > send/receive to be in enrolled in a JTA transaction. Any pointers on how
> > > > this can be done?
> > > >
> > > > -Maciej
> > > >
> > >
> > >
> >
>

Re: Transactional JMS.

Posted by Rajith Attapattu <ra...@gmail.com>.
On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
>
> Rajith,
>
> Your take appears to be based on the assumption that AXIS is communicating
> with the JMS provider directly (that is outside of a managed environment).
> In a managed environment the connection/session creation would not be an
> issue since these would  be pooled objects, with automatic transaction
> association. In this (managed) case sending message in JTA would be only a
> matter of a) providing a way to specify JNDI location of a JMS connection
> factory, and b) making sure that the session is started with the transacted
> flag set to false. In this context, the message consumption is problematic
> since it would need to involve either MDBs or some unsightly polling scheme.
>


Yes, my assumption was based on communicating with a JMS provider directly.

So assuming direct communication to the JMS provider (and no "magic" help
> from the JMS provider) , I generally agree with your comments. Certainly
> creating a connection for each connection is not acceptable (this is true
> for the non-JTA case as well).


Yes, this comment was in general for both transacted and non transacted
case. Connections are expensive and we need to reuse where it make sense.

The naming scheme that you describe would work perfectly well for us, but it
> may quickly turn into a JCA-lite project; perhaps there is some way to make
> this pluggable (a simple interface for providing a JMS connection to AXIS).
> As for reusing sessions,I think it is more trouble than its worth, and in my
> experience there is very little performance overhead here.


For Receiving we use the same session, but for sending we create a new
connection and a session.
Well Sessions are light weight, but in the case where we have a high volume
of web service invocations we will be creating and destroying a lot of
sessions unnecessarily. Setting up a session and then destroying on the
broker side does take some resources all though comparatively less than a
connection.
I agree that reusing sessions are tricky and may not be worth all the time -
but it does make sense for certain situations. For example if you have a
Service with scope='application' or scope='soap-session' that does frequent
message sending then it makse sense to maintain a session per service
instance. Here the life time of the service instance is tied to it's axis2
defined scope. We already have a session per receiver. Also if we have
several services with scope='request' and sending frequent messages then it
make sense to share a session(s) btw these services to improve performance.
Remember that, at the least creating and destroying a session involves IO
and network round trip for two calls on the broker. Now think about a
situation where you send 50,000 msg/sec.

I think with careful thought and planning we can optimize the JMS transport
without screwing up the common cases.

Also session-per-service would necessitate serializing access (since an
> XASession can only be associated with one JTA transaction), which in many
> cases would not be desirable.


Sorry if I was not clear enough. When I said session per service, I meant
session per service instance (where it make sense). So no need to serialize
access.
Ex. If you have a service with scope='soap-session' and there are two
clients talking to it, then you would have two instances of the service and
would be using two JMS sessions (or two XA sessions). So each web service
instance can run transactions independently of the other.

In the use case where services with scope='request' sharing sessions
underneath, a given JMS session will only be used by one and only one
service instance at a given time. (This will be tricky to implement, and
only be worth if there is a high traffic scenario).

Going direct, we still have a problem with receving messages. As far I know,
> it is not possible to do a JTA receive using the async MessageListener
> interface. One would need to either poll, or  use the MessageConsumer
> interfaces.


Async or sync message receive is orthogonal to the transactions. Can you
elaborate a bit more

In either case there is the issue of who begins and commits the JTA
> transaction (AXIS2 or the service), and if its the service, it is not clear
> how that interaction would look.
>
I'm more inclined toward an  MDB-like model, where AXIS starts the TX, calls
> the service, and then barring some indication to the contrary, attempts to
> commit.


IMO Axis2 should not commit or rollback automatically. Commits or rollbacks
can happen based on business decisions as well as system errors.
And in the case of a distributed transaction the decision to commit or
rollback will come from the distributed transaction manager.

If there are any system(axis2) hiccups then axis2 will/should always throw a
fault and the service author will be notified instead of axis2 doing
rollback.
In the case of a local transaction the service author may rollback and in a
distributed transaction the XA resource (XA Session) will throw an exception
in the prepare method and the the transaction manager will call rollback.

-mbs
>
> On 9/4/07, Rajith Attapattu <ra...@gmail.com> wrote:
> >
> > Maciej,
> >
> > Currently there are a few problems with doing this. Lets identify the
> > issues
> > a) We create a new connection for each invocation (sending messages)
> > b) Hence we create a new session for each invocation.
> > c) When creating a session for receiving as well as sending transacted
> > is set to true - no way to configure this.
> > d) We currently don't expose the session outside for both transport
> > sender/receiver, hence you cannot call commit or rollback on it.
> > e) Since u are using JTA I assume it's a distributed transaction. So we
> > need to create an XASession instead of a normal session.
> >
> > This can be done and here are some ideas. I spoke with Asankha briefly
> > on this topic once.
> >
> > a) Asankha pointed out a new connection is created for each invocation
> > as each service could have different connection params. (different provider,
> > username,..etc)
> > The downside of this is that creating new connections is an expensive
> > operation. Especially if the same service sends frequent messages it will
> > keep recreating connections. We should make this behaviour configurable.
> > I would like if we could reuse connections where we can. Also in most
> > cases a deployment would use a single provider and we can definitely
> > optimize for this case.
> > For this case we can get away with a single connection per axis2
> > instance and session per service (one for sending and one for listening).
> >
> > If we can name connections then we could reuse them when defining
> > services. This way we can check if an existing connection by that name
> > exists and reuse it, if not create one.
> >
> > When we reuse connections there will be keep alive issues. Most
> > providers have convenient and cheap ways of sending ping/pongs to keep the
> > connection alive.
> > So in a case where the service sends messages frequently this will help.
> > If the service sends messages rarely and the cost of keep alive is greater
> > than the occasional connection creation then the user can disable the reuse
> > option.
> >
> > b) Creating a new session for each invocation is not optimal. Since the
> > context hierarchy determines the scope of services and is independent of the
> > transport session it's ok to reuse a JMS session underneath where ever it
> > makes sense. If we introduce some thing similar to scope="transport-session"
> > in HTTP for JMS, then we can allow users to directly use the underlying JMS
> > transport similar to the way HTTP session is used.
> >
> > c) We can make the transacted property configurable. By default it will
> > be false.
> > <http://?auth=DQAAAHcAAABRNsIxA9tiVL3uczzey-x8FmU4gCUONPWKQAnlvhxhlFsCgDWBe2vo5cADP4RK1n0C-wf599ttpb3KuVGEQ1juQ4qqo7J7q47y0qAH12dW5DBAfbWjNSE-kzSN7uva1VddYFgwsvDPJHEKd2xLegIlVRPoMUsCpGd8rccaRUkjtg&shva=1>
> > Ex: <parameter name="transport.jms.SessionTransacted">true</parameter>
> >
> > d) We need to expose the JMS session. Can we put the JMS session
> > somewhere in the context hierarchy?
> > I also see a getSessionContext in TransportListener interface, However
> > SessionContext is written with HTTP in mind and is not generic enough.
> > If we put it in the content hierarchy then the service author can
> > retrieve it and call commit, rollback etc.
> >
> > e) We can create an XASession  instead of a normal session based on
> > configuration, provided the JMS provider supports it.
> > Ex. <parameter name="transport.jms.XASession">true</parameter>
> >
> > Comments are very much appreciated.
> >
> > Regards,
> >
> > Rajith
> >
> > On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
> > >
> > > Hi,
> > >
> > > I've been unable to find anything on the topic in Nabble, so I thought
> > > I'd ping you all, and Asankha in particular regarding transactions in the
> > > JMS transport implementation.
> > > In ODE we'd like to be able to consume/send messages through AXIS' JMS
> > > transport. That in itself is not a problem. However, we'd like the
> > > send/receive to be in enrolled in a JTA transaction. Any pointers on how
> > > this can be done?
> > >
> > > -Maciej
> > >
> >
> >
>

Re: Transactional JMS.

Posted by Maciej Szefler <mb...@intalio.com>.
Rajith,

Your take appears to be based on the assumption that AXIS is communicating
with the JMS provider directly (that is outside of a managed environment).
In a managed environment the connection/session creation would not be an
issue since these would  be pooled objects, with automatic transaction
association. In this (managed) case sending message in JTA would be only a
matter of a) providing a way to specify JNDI location of a JMS connection
factory, and b) making sure that the session is started with the transacted
flag set to false. In this context, the message consumption is problematic
since it would need to involve either MDBs or some unsightly polling scheme.


So assuming direct communication to the JMS provider (and no "magic" help
from the JMS provider) , I generally agree with your comments. Certainly
creating a connection for each connection is not acceptable (this is true
for the non-JTA case as well). The naming scheme that you describe would
work perfectly well for us, but it may quickly turn into a JCA-lite project;
perhaps there is some way to make this pluggable (a simple interface for
providing a JMS connection to AXIS). As for reusing sessions,I think it is
more trouble than its worth, and in my experience there is very little
performance overhead here. Also session-per-service would necessitate
serializing access (since an XASession can only be associated with one JTA
transaction), which in many cases would not be desirable.

Going direct, we still have a problem with receving messages. As far I know,
it is not possible to do a JTA receive using the async MessageListener
interface. One would need to either poll, or  use the MessageConsumer
interfaces. In either case there is the issue of who begins and commits the
JTA transaction (AXIS2 or the service), and if its the service, it is not
clear how that interaction would look. I'm more inclined toward an  MDB-like
model, where AXIS starts the TX, calls the service, and then barring some
indication to the contrary, attempts to commit.

-mbs

On 9/4/07, Rajith Attapattu <ra...@gmail.com> wrote:
>
> Maciej,
>
> Currently there are a few problems with doing this. Lets identify the
> issues
> a) We create a new connection for each invocation (sending messages)
> b) Hence we create a new session for each invocation.
> c) When creating a session for receiving as well as sending transacted is
> set to true - no way to configure this.
> d) We currently don't expose the session outside for both transport
> sender/receiver, hence you cannot call commit or rollback on it.
> e) Since u are using JTA I assume it's a distributed transaction. So we
> need to create an XASession instead of a normal session.
>
> This can be done and here are some ideas. I spoke with Asankha briefly on
> this topic once.
>
> a) Asankha pointed out a new connection is created for each invocation as
> each service could have different connection params. (different provider,
> username,..etc)
> The downside of this is that creating new connections is an expensive
> operation. Especially if the same service sends frequent messages it will
> keep recreating connections. We should make this behaviour configurable.
> I would like if we could reuse connections where we can. Also in most
> cases a deployment would use a single provider and we can definitely
> optimize for this case.
> For this case we can get away with a single connection per axis2 instance
> and session per service (one for sending and one for listening).
>
> If we can name connections then we could reuse them when defining
> services. This way we can check if an existing connection by that name
> exists and reuse it, if not create one.
>
> When we reuse connections there will be keep alive issues. Most providers
> have convenient and cheap ways of sending ping/pongs to keep the connection
> alive.
> So in a case where the service sends messages frequently this will help.
> If the service sends messages rarely and the cost of keep alive is greater
> than the occasional connection creation then the user can disable the reuse
> option.
>
> b) Creating a new session for each invocation is not optimal. Since the
> context hierarchy determines the scope of services and is independent of the
> transport session it's ok to reuse a JMS session underneath where ever it
> makes sense. If we introduce some thing similar to scope="transport-session"
> in HTTP for JMS, then we can allow users to directly use the underlying JMS
> transport similar to the way HTTP session is used.
>
> c) We can make the transacted property configurable. By default it will be
> false.
> <http://?auth=DQAAAHcAAABRNsIxA9tiVL3uczzey-x8FmU4gCUONPWKQAnlvhxhlFsCgDWBe2vo5cADP4RK1n0C-wf599ttpb3KuVGEQ1juQ4qqo7J7q47y0qAH12dW5DBAfbWjNSE-kzSN7uva1VddYFgwsvDPJHEKd2xLegIlVRPoMUsCpGd8rccaRUkjtg&shva=1>
> Ex: <parameter name="transport.jms.SessionTransacted">true</parameter>
>
> d) We need to expose the JMS session. Can we put the JMS session somewhere
> in the context hierarchy?
> I also see a getSessionContext in TransportListener interface, However
> SessionContext is written with HTTP in mind and is not generic enough.
> If we put it in the content hierarchy then the service author can retrieve
> it and call commit, rollback etc.
>
> e) We can create an XASession  instead of a normal session based on
> configuration, provided the JMS provider supports it.
> Ex. <parameter name="transport.jms.XASession">true</parameter>
>
> Comments are very much appreciated.
>
> Regards,
>
> Rajith
>
> On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
> >
> > Hi,
> >
> > I've been unable to find anything on the topic in Nabble, so I thought
> > I'd ping you all, and Asankha in particular regarding transactions in the
> > JMS transport implementation.
> > In ODE we'd like to be able to consume/send messages through AXIS' JMS
> > transport. That in itself is not a problem. However, we'd like the
> > send/receive to be in enrolled in a JTA transaction. Any pointers on how
> > this can be done?
> >
> > -Maciej
> >
>
>

Re: Transactional JMS.

Posted by Rajith Attapattu <ra...@gmail.com>.
Maciej,

Currently there are a few problems with doing this. Lets identify the issues
a) We create a new connection for each invocation (sending messages)
b) Hence we create a new session for each invocation.
c) When creating a session for receiving as well as sending transacted is
set to true - no way to configure this.
d) We currently don't expose the session outside for both transport
sender/receiver, hence you cannot call commit or rollback on it.
e) Since u are using JTA I assume it's a distributed transaction. So we need
to create an XASession instead of a normal session.

This can be done and here are some ideas. I spoke with Asankha briefly on
this topic once.

a) Asankha pointed out a new connection is created for each invocation as
each service could have different connection params. (different provider,
username,..etc)
The downside of this is that creating new connections is an expensive
operation. Especially if the same service sends frequent messages it will
keep recreating connections. We should make this behaviour configurable.
I would like if we could reuse connections where we can. Also in most cases
a deployment would use a single provider and we can definitely optimize for
this case.
For this case we can get away with a single connection per axis2 instance
and session per service (one for sending and one for listening).

If we can name connections then we could reuse them when defining services.
This way we can check if an existing connection by that name exists and
reuse it, if not create one.

When we reuse connections there will be keep alive issues. Most providers
have convenient and cheap ways of sending ping/pongs to keep the connection
alive.
So in a case where the service sends messages frequently this will help. If
the service sends messages rarely and the cost of keep alive is greater than
the occasional connection creation then the user can disable the reuse
option.

b) Creating a new session for each invocation is not optimal. Since the
context hierarchy determines the scope of services and is independent of the
transport session it's ok to reuse a JMS session underneath where ever it
makes sense. If we introduce some thing similar to scope="transport-session"
in HTTP for JMS, then we can allow users to directly use the underlying JMS
transport similar to the way HTTP session is used.

c) We can make the transacted property configurable. By default it will be
false.
<?auth=DQAAAHcAAABRNsIxA9tiVL3uczzey-x8FmU4gCUONPWKQAnlvhxhlFsCgDWBe2vo5cADP4RK1n0C-wf599ttpb3KuVGEQ1juQ4qqo7J7q47y0qAH12dW5DBAfbWjNSE-kzSN7uva1VddYFgwsvDPJHEKd2xLegIlVRPoMUsCpGd8rccaRUkjtg&shva=1>
Ex: <parameter name="transport.jms.SessionTransacted">true</parameter>

d) We need to expose the JMS session. Can we put the JMS session somewhere
in the context hierarchy?
I also see a getSessionContext in TransportListener interface, However
SessionContext is written with HTTP in mind and is not generic enough.
If we put it in the content hierarchy then the service author can retrieve
it and call commit, rollback etc.

e) We can create an XASession  instead of a normal session based on
configuration, provided the JMS provider supports it.
Ex. <parameter name="transport.jms.XASession">true</parameter>

Comments are very much appreciated.

Regards,

Rajith

On 9/4/07, Maciej Szefler <mb...@intalio.com> wrote:
>
> Hi,
>
> I've been unable to find anything on the topic in Nabble, so I thought I'd
> ping you all, and Asankha in particular regarding transactions in the JMS
> transport implementation.
> In ODE we'd like to be able to consume/send messages through AXIS' JMS
> transport. That in itself is not a problem. However, we'd like the
> send/receive to be in enrolled in a JTA transaction. Any pointers on how
> this can be done?
>
> -Maciej
>

Re: Transactional JMS.

Posted by "Asankha C. Perera" <as...@wso2.com>.
Hi Maciej

I am traveling this week and will not be able to reply in detail until 
the weekend. However I have made some enhancements to the JMS code - esp 
to re-use sessions when sending out. Currently the code is under a 
module called Synapse-transports for you to take a peek 
<http://svn.apache.org/viewvc/webservices/synapse/trunk/java/modules/transports/src/main/java/org/apache/axis2/transport/jms/> 
- once I finish testing etc. I will  commit that code into Axis2 and 
take it out from Synapse. I will also do my best to review your email 
again and Rajith's email and reply.

asankha

Maciej Szefler wrote:
> Hi,
>
> I've been unable to find anything on the topic in Nabble, so I thought 
> I'd ping you all, and Asankha in particular regarding transactions in 
> the JMS transport implementation.
> In ODE we'd like to be able to consume/send messages through AXIS' JMS 
> transport. That in itself is not a problem. However, we'd like the 
> send/receive to be in enrolled in a JTA transaction. Any pointers on 
> how this can be done?
>
> -Maciej