Spring MVCアプリケーションの基盤となるJTA実装としてAtomikosを使用して、埋め込みH2 DBとActiveMQで分散トランザクションを設定しようとしています。 私は遭遇しているエラーに関連したウェブ/ stackoverflowのほとんどすべてのページに従ってきましたが、それを理解することはできませんでした。ここでAtomikosでActiveMQと埋め込みH2を含む分散トランザクションを設定できません
は、コンフィギュレーションの関連する部分です:
@Autowired
@Bean(name = "transactionManager")
public PlatformTransactionManager getJtaTransactionManager(TransactionManager usrTxMgr,
@Qualifier("AtomikosUserTransaction") UserTransaction usrTx) {
return new JtaTransactionManager(usrTx, usrTxMgr);
}
@Autowired
@Bean(name = "transactionManager")
public PlatformTransactionManager getJtaTransactionManager(TransactionManager usrTxMgr,
@Qualifier("AtomikosUserTransaction") UserTransaction usrTx) {
return new JtaTransactionManager(usrTx, usrTxMgr);
}
@Bean(name = "AtomikosTransactionManager", initMethod = "init", destroyMethod = "close")
public TransactionManager getAtomikosTransactionManager() {
return new UserTransactionManager();
}
@Bean(name = "AtomikosUserTransaction")
public UserTransaction getAtomikosUserTransaction() throws SystemException {
UserTransactionImp usrTx = new UserTransactionImp();
usrTx.setTransactionTimeout(30);
return usrTx;
}
@Bean(name = "H2X")
public AtomikosDataSourceBean getXADataSource() {
JdbcDataSource h2x = new JdbcDataSource();
h2x.setURL("jdbc:h2:˜/test1" + ";" + "INIT=RUNSCRIPT FROM 'classpath:sql/create-db.sql'");
h2x.setUser("sa");
h2x.setPassword("");
AtomikosDataSourceBean atkDs = new AtomikosDataSourceBean();
atkDs.setXaDataSource(h2x);
atkDs.setUniqueResourceName("AtomikosXADataSource");
return atkDs;
}
@Autowired
@Bean(name = "H2TemplateX")
public NamedParameterJdbcTemplate getJdbcTemplateX(@Qualifier("H2X") AtomikosDataSourceBean atkDs) {
return new NamedParameterJdbcTemplate(atkDs);
}
@Bean(name = "ActiveMQXACF")
public ConnectionFactory getXAConnectionFactory(@Value("${brokerURL:tcp://localhost:61616}") String brokerURL) {
ActiveMQXAConnectionFactory activeMQXAConnectionFactory = new org.apache.activemq.ActiveMQXAConnectionFactory(brokerURL);
AtomikosConnectionFactoryBean atomikosJMSConnectionFactoryBean = new AtomikosConnectionFactoryBean();
atomikosJMSConnectionFactoryBean.setUniqueResourceName("AtomikosJMSConnectionFactory");
atomikosJMSConnectionFactoryBean.setXaConnectionFactory(activeMQXAConnectionFactory);
return atomikosJMSConnectionFactoryBean;
}
@Bean(name = "JMSTemplateX")
public JmsTemplate getXAJMSTemplate(@Autowired @Qualifier("ActiveMQXACF") ConnectionFactory cf, @Value("${JMSDestination}") String destination) {
JmsTemplate jt = new JmsTemplate();
jt.setConnectionFactory(cf);
jt.setDefaultDestinationName(destination);
jt.setSessionTransacted(true);
return jt;
}
これらは@Transactionalを注釈を付けている方法です。それらはすべて異なるサービス/リポジトリ/コンポーネントクラスにあります。デバッグ中に春の取引を置く
@Transactional
public void saveMessage(String message) {
messageSaver.insertMessage(message);
processor.processMessage(message);
}
@Transactional
public void processMessage(final String message){
jmsTemplate.send("Queue1", new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
@Transactional
public void insertMessage(String msg) {
if (msg.toLowerCase().contains("bad")) throw new RuntimeException("Can't Commit to DB !!");
Map<String, Object> params = new HashMap<String, Object>();
params.put("msg", msg);
String sql = "insert into TBL_MESSAGE (message) values(:msg)";
jdbcTemplateX.update(sql, params);
}
、私は春が正しくトランザクションメソッドとAtomikos UserTransactionManagerとUserTransactionImpクラスを登録していることがわかります。 短縮ログ:
Adding transactional method 'business.MessageDaoImpl.insertMessage
Adding transactional method 'business.OrderProcessor.processMessag
Adding transactional method 'business.MessageServiceService.saveMe
org.springframework.transaction.jta.JtaTransactionManager - Using JTA UserTransaction: [email protected]
org.springframework.transaction.jta.JtaTransactionManager - Using JTA TransactionManager: [email protected]
これらはAtomikosデバッグログからいくつかのログです:メッセージを送信すると、メッセージの送信がI JTAトランザクションのコンテキストで実行されるべきであると述べていながら
DEBUG http-nio-8080-exec-1 com.atomikos.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'AtomikosXADataSource': getConnection()...
INFO http-nio-8080-exec-1 com.atomikos.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'AtomikosXADataSource': init...
WARN http-nio-8080-exec-1 com.atomikos.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'AtomikosXADataSource': poolSize equals default - this may cause performance problems!
INFO http-nio-8080-exec-1 com.atomikos.jdbc.AtomikosDataSourceBean - AtomikosDataSoureBean 'AtomikosXADataSource': initializing with [ xaDataSourceClassName=null, uniqueResourceName=AtomikosXADataSource, maxPoolSize=1, minPoolSize=1, borrowConnectionTimeout=30, maxIdleTime=60, reapTimeout=0, maintenanceInterval=60, testQuery=null, xaProperties=[], loginTimeout=0, maxLifetime=0]
INFO http-nio-8080-exec-1 com.atomikos.datasource.xa.XATransactionalResource - AtomikosXADataSource: refreshed XAResource
DEBUG http-nio-8080-exec-1 com.atomikos.jdbc.AtomikosConnectionProxy - atomikos connection proxy for conn5: url=jdbc:h2:˜/test1 user=SA: calling prepareStatement(insert into TBL_MESSAGE (message) values(?))...
DEBUG http-nio-8080-exec-1 com.atomikos.jdbc.AtomikosConnectionProxy - atomikos connection proxy for conn5: url=jdbc:h2:˜/test1 user=SA: close()...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosConnectionFactoryBean - AtomikosConnectionFactoryBean 'AtomikosJMSConnectionFactory': createConnection()...
INFO http-nio-8080-exec-1 com.atomikos.jms.AtomikosConnectionFactoryBean - AtomikosConnectionFactoryBean 'AtomikosJMSConnectionFactory': init...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosConnectionFactoryBean - AtomikosConnectionFactoryBean 'AtomikosJMSConnectionFactory': getReference()...
INFO http-nio-8080-exec-1 com.atomikos.jms.AtomikosConnectionFactoryBean - AtomikosConnectionFactoryBean 'AtomikosJMSConnectionFactory': initializing with [ xaCo[email protected]59883d41, xaConnectionFactoryClassName=null, uniqueResourceName=AtomikosJMSConnectionFactory, maxPoolSize=1, minPoolSize=1, borrowConnectionTimeout=30, maxIdleTime=60, reapTimeout=0, maintenanceInterval=60, xaProperties=[], localTransactionMode=false, maxLifetime=0, ignoreSessionTransactedFlag=true]
INFO http-nio-8080-exec-1 com.atomikos.datasource.xa.XATransactionalResource - AtomikosJMSConnectionFactory: refreshed XAResource
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsConnectionProxy - atomikos connection proxy for resource AtomikosJMSConnectionFactory: creating XA-capable session...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa session proxy for resource AtomikosJMSConnectionFactory: calling toString on JMS driver session...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa session proxy for resource AtomikosJMSConnectionFactory: calling createQueue on JMS driver session...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa session proxy for resource AtomikosJMSConnectionFactory: calling createProducer on JMS driver session ActiveMQSession {id=ID:IG11061-58249-1492635876500-5:2:2,started=false}
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa session proxy for resource AtomikosJMSConnectionFactory: calling createTextMessage on JMS driver session...
DEBUG http-nio-8080-exec-1 com.atomikos.jms.AtomikosJmsMessageProducerProxy - atomikos MessageProducer proxy for ActiveMQMessageProducer { value=ID:IG11061-58249-1492635876500-5:2:2:1 }: send (message)...
WARN http-nio-8080-exec-1 com.atomikos.jms.ConsumerProducerSupport - atomikos MessageProducer proxy for ActiveMQMessageProducer { value=ID:IG11061-58249-1492635876500-5:2:2:1 }: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
エラー@Transactionalアノテーションが存在するため、最初のメソッド呼び出しで作成されると仮定していました。
私はエラーを生成Atomikosクラスのソースを見たがmuch.Theエラーが参加して起こる()メソッドを見つけ出すことができませんでした:
protected void enlist() throws JMSException {
CompositeTransaction ct = null;
CompositeTransactionManager ctm = this.getCompositeTransactionManager();
boolean enlist = false;
if(ctm != null) {
ct = ctm.getCompositeTransaction();
if(ct != null && ct.getProperty("com.atomikos.icatch.jta.transaction") != null) {
enlist = true;
}
}
if(enlist) {
this.registerSynchronization(ct);
try {
this.state.notifyBeforeUse(ct);
} catch (InvalidSessionHandleStateException var6) {
String msg1 = "error during enlist: " + var6.getMessage();
LOGGER.logWarning(this + ": " + msg1);
AtomikosJMSException.throwAtomikosJMSException(msg1, var6);
}
} else {
String msg = "The JMS session you are using requires a JTA transaction context for the calling thread and none was found.\nPlease correct your code to do one of the following: \n1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or\n2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or\n3. create a non-transacted session and do session acknowledgment yourself, or\n4. set localTransactionMode to true so connection-level commit/rollback are enabled.";
LOGGER.logWarning(this + ": " + msg);
AtomikosTransactionRequiredJMSException.throwAtomikosTransactionRequiredJMSException(msg);
}
任意の助けをいただければ幸いに!!