如何在Spring Programmatic事务中获取transactionManager引用

时间:2012-01-27 13:43:05

标签: spring transactions jms

我想在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启动的事务,以便我可以以编程方式处理事务

2 个答案:

答案 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提取基础事务管理器   在运行时,我们可以注入下图中显示的特定于平台的事务管理器。

enter image description here

我们可以通过以下两种方式获得Spring编程方法中的事务管理器参考:

  1. 使用界面 PlatformTransactionManager:我们必须明确创建TransactionDefinitionTransactionStatus对象。
  2. 例如:

           @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;
              }
    
    1. 使用课程 TransactionTemplate
    2. 我们不必明确创建TransactionDefinitionTransactionStatus对象。 TransactionTemplate提供了一个名为 execute 的回调方法,我们可以在其中添加我们想要在事务中包装的业务逻辑。

      我们可以使用两种类型的回调方法来包装我们的代码,即TransactionCallbackWithoutResultTransactionCallback(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
         }
       });
      }