我想在JMS应用程序中使用spring programmatic事务来接收来自队列的消息。同时,我想将队列包含在事务范围内。
使用Spring DefaultMessageListnereContainer并在其中注入事务管理器。但是,不确定如何以编程方式提交或回滚此事务的引用?
我阅读并理解"处理交易中的消息"这里 http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/jms.html#jms-tx-participation
我的2项要求是 - 1)XA事务因此注入JtaTransactionManager, 2)使用程序化事务 - 这里我需要帮助如何在代码中引用spring启动的事务,以便我可以以编程方式处理事务
答案 0 :(得分:11)
首先必须注入org.springframework.transaction.PlatformTransactionManager
- 这是一个像所有其他人一样的普通bean:
@Resource
private PlatformTransactionManager transactionManager;
现在,您可以将其与TransactionTemplate
一起使用:
final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallback<String>() {
@Override
public Object doInTransaction(TransactionStatus status) {
transactionManager.rollback(status);
return ":-(";
}
});
相当多的代码,所以这是你应该如何做到这一点:
@Transactional
public void onMessage(Message message) {
//rollback:
throw new HoustonException("We've got a problem!");
}
如果从RuntimeException
方法抛出@Transactional
,它将自动回滚该事务。否则它将被提交。
请注意,这并不意味着JMS和数据库正在处理同一个事务!当您抛出异常时,JMS代理将尝试重新传递消息,但是在提交数据库事务后代理可能会失败。如果您需要100%确定JMS和DB更新都是原子的,那么您需要分布式事务管理器。
答案 1 :(得分:0)
Spring使用
PlatformTransactionManager
提取基础事务管理器 在运行时,我们可以注入下图中显示的特定于平台的事务管理器。
我们可以通过以下两种方式获得Spring编程方法中的事务管理器参考:
PlatformTransactionManager
:我们必须明确创建TransactionDefinition
和TransactionStatus
对象。例如:
@Resource
private PlatformTransactionManager transactionManager;
public void create(String name, Integer age, Integer marks, Integer year){
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
//jmsTemplate statements
transactionManager.commit(status);
} catch (DataAccessException e) {
System.out.println("Error in creating record, rolling back");
transactionManager.rollback(status);
throw e;
}
TransactionTemplate
:我们不必明确创建TransactionDefinition
和TransactionStatus
对象。 TransactionTemplate
提供了一个名为 execute 的回调方法,我们可以在其中添加我们想要在事务中包装的业务逻辑。
我们可以使用两种类型的回调方法来包装我们的代码,即TransactionCallbackWithoutResult
和TransactionCallback(T)
例如:
@Resource
private TransactionTemplate transactionTemplate;
public void deleteUser(final int uid) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus paramTransactionStatus) {
try{
//statements
}catch (Exception e) {
//use this to rollback exception in case of exception
paramTransactionStatus.setRollbackOnly();
}
}
});
}
public int insertUser(final User user) {
//use TransactionCallback handler if some result is returned
return transactionTemplate.execute(new TransactionCallback<Integer>() {
public Integer doInTransaction(TransactionStatus paramTransactionStatus) {
//statements
}
});
}