だから私はJMSトピックに発行するこのコードを持っています:
public void notifyCreateListeners(MyCreatedObject payload) {
logger.trace("ServiceImpl.notifyCreateListeners");
TopicConnection conn = null;
TopicSession session = null;
Topic topic = null;
try {
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.factory.url.pkgs","org.jboss.naming");
props.setProperty("java.naming.provider.url", "jnp://localhost:49227");
Context context = new InitialContext(props);
TopicConnectionFactory tcf = (TopicConnectionFactory) context.lookup("/ConnectionFactory");
conn = tcf.createTopicConnection(JbossJaasAuthenticator.principal, JbossJaasAuthenticator.credentials);
topic = (Topic)context.lookup("topic/create_notify_topic");
session = conn.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
conn.start();
TopicPublisher send = session.createPublisher(topic);
ObjectMessage message = session.createObjectMessage();
message.setObject(payload);
send.publish(message);
conn.close();
} catch (Exception e) {
logger.error("an exception occurred notifying create listeners", e);
}
}
私は SOAP を介してこのコードを常に呼び出していますが、1 ~ 2 秒もかからず、かなり高速に実行されます。ただし、私が抱えている問題は、このコードが「send.publish(message)」でハングすることがあり、5分から15分という非常に長い時間がかかり、最終的に完了するか、トランザクションリーパーによって強制終了されることです:
[2015-04-01 11:38:00,198] WARN com.arjuna.ats.arjuna.logging.arjLoggerI18N [com.arjuna.ats.arjuna.coordinator.BasicAction_40] - Abort called on already aborted atomic action -6ec596b6:e039:551a4e56:ff03b
[2015-04-01 11:38:00,206] ERROR org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS SOAP request exception
javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
.....
Caused by: javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.inactive] [com.arjuna.ats.internal.jta.transaction.arjunacore.inactive] The transaction is not active!
奇妙な点は、このメソッドにトランザクションを使用していないことです。これは、DB に「MyCreatedObject」が作成されるこのメソッドの前のメソッドで確認したため、どのトランザクションが死神殺しなのかわかりません。
質問 1: リーパーがどのトランザクションを強制終了しているかを判断するにはどうすればよいですか? 「com.arjuna」でトレースを有効にしましたが、有用なものは何も出力されません。
質問 2: send メソッドのタイムアウトを発生させるにはどうすればよいですか? TopicPublisher の timeToLive を 120000 (2 分) に設定してみましたが、効果がないようです。
最終的には、トピックへの公開が遅れている理由と、この公開に何らかのタイムアウトを設定することでどのように干渉できるかを判断することが理想的です。なぜなら、この部分はそれほど重要ではないためです。パブリッシュが失敗した場合に全体的な SOAP 呼び出しがエラーで終了するようにするには、エラーをログに記録して正常に終了させたいだけです。この「notifyCreateListeners」メソッドを別のスレッドで呼び出すことを考えています。これは、一定時間後に強制終了します (まだアクティブな場合)。これは実行可能な解決策ですか、それとも何か他のものをお勧めできますか?