我希望在从队列接收消息的JMS应用程序中使用spring编程事务。同时,我希望将队列包含在事务范围中。
使用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启动的事务的引用,以便我能够以编程方式处理事务。
发布于 2012-01-27 13:52:24
首先必须注入org.springframework.transaction.PlatformTransactionManager --它和所有其他bean一样,是一个普通的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代理将尝试重新传递消息,但是在DB事务提交之后,代理很可能会失败。如果您需要100%确定JMS和DB更新都是原子性的,则需要分布式事务管理器。
发布于 2016-01-26 05:22:44
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
}
});
}https://stackoverflow.com/questions/9034101
复制相似问题