跳到主要内容

使用事务性会话

事务性会话允许客户端应用程序将多个消息发送和/或接收操作组合在一起,形成称为本地事务的单一原子单元。每个事务性会话可以支持一系列事务。

注意:只有保证消息(即具有持久化或非持久化传输模式的消息)可以通过事务发布或接收;直接消息不能用于事务。因此,事务性会话只能与保证传输模式一起使用(参阅消息传输模式)。要使用保证传输模式,JNDI 连接工厂中的直接传输消息传递属性(参阅消息传递属性)必须设置为 false

要以事务方式发布和/或消费消息,客户端应用程序必须首先建立一个允许事务性会话和 XA 事务的 JMS 连接到事件代理。JMS 连接必须使用在事件代理上配置的客户端用户名帐户,该帐户被分配了一个启用了 allow‑transacted‑sessions 属性的客户端配置文件(默认情况下,此属性未启用)。有关管理员如何配置客户端用户名及其分配的客户端配置文件的信息,请参阅配置客户端身份验证。

成功建立 JMS 连接后,客户端必须创建一个事务性会话。然后,客户端应用程序可以获取一个 MessageProducer 以建立一个生产者流来发布消息,和/或获取一个 MessageConsumerTopicSubscriber 以建立一个消费者流来在该事务性会话中接收消息。尽管管理员可以修改此值,但默认情况下,客户端可以在单个事务中发布和/或消费最多 256 条消息。有关更多信息,请参阅配置每个事务的最大消息数。

在事务中发布和接收的消息会在事件代理上暂存。要完成事务中的所有消息发送和接收操作,必须提交事务。或者,也可以回滚事务,以取消其所有发布和接收操作。完成一个事务后,会自动开始另一个事务。

事务只能用于单个客户端和 JMS 代理之间;它不能跨越多个客户端。例如,如下面的图所示,客户端 A 可以使用事务向 JMS 代理上的队列目标发布消息,客户端 B 可以使用事务从同一队列消费消息。但是,每个客户端使用独立的会话,并且每个客户端必须使用单独的事务。JMS 代理作为消息在被 commit() 发布或消费之前暂存的地方,用于分离客户端 A 的事务消息生产和客户端 B 的事务消息消费。

每个客户端的事务

img

客户端可以在单个事务性会话中同时使用生产者和消费者。如下图所示,在这种情况下,当客户端提交事务时,消费者从端点接收暂存的消息 A,同时消息 B 和 C 被发布到同一目标端点。

事务和提交

img

线程考虑

事务性会话仅支持单线程使用(例外是任何应用程序线程都可以调用 close() 来关闭事务性会话)。属于事务性会话的所有生产者和消费者流必须由同一线程顺序访问。

同步消费者

当使用同步消息消费者时,单个应用程序线程负责所有发送和接收操作,并且必须提交或回滚事务。应用程序线程对事务性会话的生产者和消费者进行序列化访问。

异步消费者

当使用异步消息消费者时,API 拥有的线程将消息传递给注册的消息监听器。此线程用于发送消息,并且必须提交或回滚事务。API 线程对事务性会话的生产者和消费者进行序列化访问。