gpt4 book ai didi

java - JMS和EJB中事务的正确使用

转载 作者:行者123 更新时间:2023-11-30 03:34:12 25 4
gpt4 key购买 nike

我想知道如何在 EJB 容器内正确使用 JMS 事务。我找到了这段代码,它在无状态 bean 中使用 JMS 发送消息:

@Stateless
public class SendEventsBean {

private static final Logger log = Logger.getLogger(SendEventsBean.class);

@Resource(mappedName = "jms/MyConnectionFactory")
private ConnectionFactory jmsConnectionFactory;

@Resource(mappedName = "jms/myApp/MyQueue")
private Queue queue;

public void sendEvent() {
Connection jmsConnection = null;
try {
connection = jmsConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
MyObj obj = new MyObj(1, "Foo");
ObjectMessage myObjMsg = session.createObjectMessage(obj);
producer.send(myObjMsg);
} catch (JMSException jmxEx) {
log.error("Couldn't send JMS message: ", jmsEx);
}finally{
if (jmsConnection != null) {
try {
jmsConnection.close();
}catch(JMSException ex) {
log.warn("Couldn't close JMSConnection: ", ex);
}
}
}
}

(来自 When should I close a JMS connection that was created in a stateless session bean? )

默认情况下,事务由容器管理,事务属性为“必需”。假设客户端直接调用sendEvent(),那么事务从sendEvent()的开头开始,到sendEvent()结束时结束(->在该方法的最后执行一次提交)。在方法最后发生提交之前关闭连接(jmsConnection.close())不是错误的吗?

此外,我想知道设置事务属性和在 createSession() 中设置 true/false 是如何交互的。

如果容器已经启动了一个事务(使用容器管理的事务),那么设置 createSession(true,...) 是否有意义?这是否会在 JTA 事务内为 JMS 消息(而不是 DB)创建一个新事务?

对于 createSession(false, ...) 我是对的吗,消息仍然是事务性的,因为事务是由容器启动的?

最佳答案

Isn't it wrong to close the connection (jmsConnection.close()) BEFORE the commit occurs at the very end of the method?

没有。关闭连接与 JTA 事务内的提交无关(这里就是这种情况,它是带有 CMT 的 ejb)。这只是适当且必要的清理。请注意,这些是容器返回的连接,底层事务管理器知道如何使用资源来提交事务。 JDBC 连接也是如此。

Does it make sense setting createSession(true,...) if there is already a transaction started by the container (using container managed transactions)?

对于 Weblogic,您绝对应该使用非事务性 session 。但是,对于 JMS 连接使用 XA 连接工厂很重要。

http://docs.oracle.com/cd/E11035_01/wls100/jms/trans.html#wp1031645 http://www.informit.com/articles/article.aspx?p=26137&seqNum=8

然而,与 JBOSS 相关的文章建议即使在 CMT ejb 中也将 createSession(true...) 设置为良好实践

https://developer.jboss.org/thread/213629?tstart=0&_sscc=t http://www.coderanch.com/t/606786/EJB-JEE/java/EJB-CMT-sending-JMS-message

无论设置如何,都必须强制使用基于 JCA/XA 的连接工厂。

And with createSession(false, ...) am I right, that messages are nevertheless transactional because of the transaction started by the container?

没有。如上所述,您必须使用 XA 连接工厂。

关于java - JMS和EJB中事务的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28365524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com