繁体   English   中英

JMS和Java EE事务

[英]JMS and Java EE transactions

如果您在EJB容器中运行了一些Java代码(由JMS消息传递启动),并且该代码将另一个JMS消息放入同一队列中,那么如何阻止该消息传递,直到将其踢掉的代码完成为止和它的交易已提交? 基本上,我遇到交易并发问题。 我有JMS消息A所启动的代码(在EJB中)。该代码完成了一些工作,然后进行了数据库插入(由于容器管理的EJB事务,直到所有这些代码执行完毕,它才提交)。 然后,它放入一条消息(消息B),该消息具有刚插入队列中的数据库行的ID。 然后,它会在同一事务中完成一些其他工作,而这需要花费一些时间。

好吧,将带有数据库行ID的消息放入队列后不久,它就被传递并启动了代码,该代码试图查询由消息A所启动的代码插入的行。麻烦是,那插入该行的代码仍在执行,并且其事务尚未提交。 因此,有问题的数据库行不在要查询的数据库中。 结果是由于消息B错误而启动的代码无法找到所需的数据库行。

我该如何预防? 我已经完成了有关Java EE容器中的JMS和事务的数小时研究。 我读过的一篇教程说,您无法在同一笔交易中收到消息并发送回复。 因此,在所有事务完成之前,容器是否不应该将消息提交到队列中?

抱歉,这个问题很乱。 我正在尽力解释。 这里粘贴的代码太多了。 但是环境是WildFly 8.1,可执行代码在无状态EJB内,JPA用于数据库访问,消息在队列中,而不是主题中。 我希望有足够的信息。

// How factory and queues are declared in java code:

@Resource(mappedName = "java:/ConnectionFactory")
ConnectionFactory connectionFactory;

@Resource(mappedName = "java:jboss/exported/jms/queue/quequeA")
Queue queueA;

@Resource(mappedName = "java:jboss/exported/jms/queue/quequeB")
Queue queueB;

//Sending message:

TextMessage message = session.createTextMessage("some message goes here");
MessageProducer producer = session.createProducer(queueA); // samething for queueB
producer.send(message);

// how queues are configured in WidlFly's standalone.conf :

<jms-queue name="quequeA">
    <entry name="queue/quequeA"/>
    <entry name="java:jboss/exported/jms/queue/quequeA"/> <!-- same thing for queueB -->
</jms-queue>

<address-setting match="jms.queue.quequeA">
    <dead-letter-address>jms.queue.DLQ</dead-letter-address>
    <redelivery-delay>5000</redelivery-delay>
    <max-delivery-attempts>1</max-delivery-attempts>
    <max-size-bytes>10485760</max-size-bytes>
    <page-size-bytes>1048576</page-size-bytes>
    <address-full-policy>PAGE</address-full-policy>
    <message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>

// creating connection and session:
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // note: the application is running in the Java EE web/EJB environment, so both "fasle" and auto_acknowledge arguments shoudl be ignored according to the javadoc. I'm trying to use container-managed transactions for everything

我不得不更改常规连接工厂:

@Resource(mappedName = "java:/ConnectionFactory")
ConnectionFactory connectionFactory;

到XA连接工厂:

@Resource(mappedName = "java:/JmsXA")
XAConnectionFactory connectionFactory;

这使事情一开始就停止了,因为我只在@PostConstruct中为每个EJB初始化一次连接,并在带注释的@PreDestroy方法中将其关闭。 因此,除此之外,我还必须将连接和会话生成移到每个方法的开头,并在每个方法的末尾将其关闭。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM