我正在尝试使用spring + atomikos设计一个应用程序,该应用程序读取一批N条消息并将它们持久保存到单个事务中的数据库中。它必须是一批消息,因为数据在批量生成时才是一致的,即单个消息不足以进行一致的事务。此外,每条消息有一个交易绝对会影响我的表现。这不是典型的JMS + DB应用程序,因此我很难在线查找示例(我尝试使用在atomikos网站上建议的MessageListener,但每个消息创建一个事务)。使用Spring实现这一目标的最佳方法是什么? 感谢
乔瓦尼
答案 0 :(得分:0)
我认为您的问题与Spring或Atomikos无关。这更像是一个设计问题。
如果您需要在单个事务中提交所有消息,请在将完整消息发送到持久层之前将它们全部合并到更大的结构中。
答案 1 :(得分:0)
弄清楚我需要做什么。在我的spring配置文件中,我需要配置以下内容:
org.springframework.transaction.jta.JtaTransactionManager
类的实例(例如配置为使用atomikos),其中注入了“transactionManager”和“userTransaction”依赖项,例如,类com.atomikos.icatch.jta.UserTransactionManager
和com.atomikos.icatch.jta.UserTransactionImp
的实例; <tx:annotation-driven transaction-manager="txManager">
标记在客户端代码中使用注释驱动的事务; com.atomikos.jms.AtomikosConnectionFactoryBean
的实例; com.tibco.tibjms.TibjmsQueue
或类似的实例; com.atomikos.jdbc.AtomikosDataSourceBean
(或com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean
的实例); 自定义DAO类的一个实例,它注入了先前定义的JmsTemplate和SqlUpdate对象:此类将有一个或多个带注释的@Transactional
方法,它们将使用JmsTemplate执行事务以接收消息和SqlUpdate (s)将它们保留在数据库中,例如,它可能是一个类似于这样的类:
public class MyDao{
JmsTemplate jmsTemplate; // getter/setter omitted for clarity
BatchSqlUpdate sqlUpdate; // getter/setter omitted for clarity
@Transactional
public void persistMessages(int n){
// map used for the sqlUpdate object
Map<String, Object> params = new HashMap<>();
// need to reset this since it's being reused
sqlUpdate.reset();
for(int i=0;i<n;i++){
// retrieve a message synchronously
Message msg = jmsTemplate.receive();
// transform the message
doSomeMagic(msg,params);
// set parameters in the SQL
sqlUpdate.updateByNamedParam(params);
}
// now the batch can be flushed
sqlUpdate.flush();
}
private void doSomeMagic(Message msg, Map<String,Object> params){
// implementation is application-dependent!
// the only assumption is that somehow the
// message can be used to set the named
// parameters in the sqlUpdate object
}
}
唯一值得注意的是DAO 必须是弹簧管理的,因为使用注释需要spring来创建代理。