Clebert,
On 10/11/2011 15:31, Clebert Suconic wrote:
>
>
> What I just thought also was adding the idea of a context.
>
> in 90% of the cases I have seen, users are always creating a consumer within a single Session. (because you
> have also
> the requirement of a session per thread, per the spec).
>
>
> I'm not sure I follow. A Consumer is always tied to a single Session. Do you mean that users are always creating
> one Consumer per Session?
>
>
> It's easier to say this in Javanes than English. What I see users doing most of time is this:
>
>
> Connection connReceiver = cf.createConnection(....);
> Session sessionReceiver = connReceiver.createSession(....);
> Consumer receiver = sessionReceiver = sessionReceiver.createConsumer(...);
>
>
> i.e. a consumer will have a single connection and single session.
>
>
> Actually, what I see a lot also is this, through JMSTemplate (which I hate it, since it teaches users to use message
> systems synchronously):
>
>
> Connection connReceiver = cf.createConnection(....);
> Session sessionReceiver = connReceiver.createSession(....);
> Consumer receiver = sessionReceiver = sessionReceiver.createConsumer(...);
> Message message = receiver.receive();
> connReceiver.close();
>
> ** There is some caching done eventually on JMSTEmplate... but I don't want to discuss the template itself.
>
>
>
> What I'm saying is.. that in 90% of the cases, users will have a 1 to 1 relationship between:
>
> - consumer <-> session <-> connection
> - producer <-> session <-> connection.
>
>
>
> By suggesting a "context" object you seem to be re-inventing the Session, so I don't see the benefit.
>
>
> The context / session would be encapsulated. This method would only be used on the cases where you need more than one
> object at the same context (or session if you prefer to call it that way).
>
> On the supposedly new API, doing this:
>
> NewConsumer cons = connectionFactory.createConsumer(... queue1);
> NewProducer prod = connectionFactory.createProducer(....queue2);
>
>
>
> Will have you creating two contexts.
>
>
> If you want a commit call on cons to also commit prod, you would need both as part of the same context.
>
>
> You could either do something like:
>
>
> prod = cons.getContext().createProducer();
>
>
>
>
> Or, you could have it encapsulated...
>
> cons.createSameContextProducer(...);
>
>
> I guess I'm proposing merging connection, session and producer altogether. And connection, session and consumer.
>
> And the connections.. etc.. would be encapsulated.
>
>
> I'm just trying to solve the scenario with 2 objects as part of the same local transaction, without requiring XA.
>
> (again.. just a brainstorm).
OK, so just to compare your suggestion with mine (and thinking of Java EE only):
For sending messages:
We're both proposing merging connection, session and producer.
I've suggested we call the consolidated object a "newConnection" or perhaps a "context" (which is a meaningless word we
haven't used in JMS yet), you suggest calling it a "producer".
For synchronously receiving messages:
I'm proposing merging connection and session to give the same "newConnection" or "context" object as before. However I
think we still need a separate "producer" object, one for each destination, for the reasons I explained in my other
mail: to allow the application to signify the intention to receive message prior to actually calling receive().
If you want to send a message and synchronously consume a message in the same transaction, in my proposal you would perform:
NewConnection newConnection = connectionFactory.createConnection(false,Session.AUTO_ACKNOWLEDGE);
NewConsumer newConsumer = newConnection.startReceiving(queue1,messageListener,messageSelector,noLocal);
Message someMessage1 = newConsumer.receive(timeout);
TextMessage textMessage = newConnection .createTextMessage(payload);
NewConnection.send(queue2,textMessage,DeliveryMode.PERSISTENT,0,0);
In your proposal you would perform:
NewConsumer cons = connectionFactory.createConsumer(queue1,false,Session.AUTO_ACKNOWLEDGE);
Context context = cons.getContext();
NewProducer prod = cons connectionFactory.createProducer(queue2);
TextMessage textMessage = // where will createMessage go?
prod.send(textMessage);
I think my proposal is simpler in concept: your suggestion would need createProducer and createConsumer in two places,
on the connectionFactory and on the Context, which I don't think is an improvement.
(The above examples assume the transaction is committed by the transaction manager, and since they use the same
underlying session there's no need for two-phase commit)
Nigel