Question: I am a newbie to JMS. So this may be a really noob question for the experts out here in SO.
However I am having difficulty trying to grok one very important concept of how JMS has been laid out to work.

From the [Javadoc of the *JMS Session*](http://grepcode.com/file/repository.springsource.com/javax.jms/com.springsource.javax.jms/1.1.0/javax/jms/Session.java#Session)(bold emphasis mine)

> 
> A Session object is a **single-threaded context** for producing and
>  consuming messages. Although it may allocate provider resources
>  outside the Java virtual machine (JVM), it is considered a lightweight
>  JMS object.
> 
> 
> 

I thought that the main advantage of JMS is *asynchronous delivery of messages*. The term *asynchronous* automatically lends itself to the notion of multiple threads concurrently producing and consuming messages. So I am confused with the concept of a single threaded context for the all important `Session` object. What am I missing here?

Answer: 
Its for the same reason that JTA is single threaded. There aren't any hard guarantees about how/when threads are scheduled to run. In addition, without synchronization there are no guarantees about when threads will complete their work. Given these constraints it is difficult to create transactional guarantees while maintaining the benefits of parallel processing. 

For instance, if I spawn a transaction, then spawn a thread that sends messages on that transaction, but arbitrarily commit the transaction in the main thread, what should the transaction manager do(ignore the `commit()`? fail the `send()`?). What if If I have other transactional work(database commits) that haven't completed, but my message sending thread is done and has called `commit()`? What if a thread spins up and starts more work while the TransactionManager is trying to determine `2-Phase-Commit` status of all the transaction participants?

Transaction API's are all based on well defined units of work. These API's are pretty clear cut when the unit of work runs in a single thread. Things become complicated otherwise and are covered by implementations not addressed by the Java EE spec. These transaction managers allow nested transactions and/or transactions that span multiple threads. These implementations use very carefully designed synchronization, have limited use cases, and likely just ends up serializing the work anyway.

For most users, the primary benefit of JMS is similar to that of any message based actors system. Many discrete steps can pull messages of a queue, process them, advance to the next step by placing the result on another queue. If any step becomes a bottleneck you can just add more processing agents(MDBs, spring beans, etc.). Each agent does its processing on a single thread and you scale to multiple cores by creating more agents.
The `Session` class handles transactions. So while there is normally only one `Connection`, you can have multiple threads having their own session context, each with its individual transaction context.