Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Spring编程事务中获取transactionManager引用_Spring_Transactions_Jms - Fatal编程技术网

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

如何在Spring编程事务中获取transactionManager引用,spring,transactions,jms,Spring,Transactions,Jms,我想在从队列接收消息的JMS应用程序中使用spring编程事务。同时,我希望将队列包括在事务范围中 使用Spring DefaultMessageListenerContainer并在其中注入事务管理器。但是,不确定如何获取此事务的引用以编程方式提交或回滚 我在这里阅读并理解“在事务中处理消息” 我的两项要求是— 1) XA事务管理器, 2) 使用编程事务-这里我需要帮助如何在代码中获得对spring启动的事务的引用,以便我能够以编程方式处理事务您首先必须注入org.springframew

我想在从队列接收消息的JMS应用程序中使用spring编程事务。同时,我希望将队列包括在事务范围中

使用Spring DefaultMessageListenerContainer并在其中注入事务管理器。但是,不确定如何获取此事务的引用以编程方式提交或回滚


我在这里阅读并理解“在事务中处理消息”

我的两项要求是— 1) XA事务管理器,
2) 使用编程事务-这里我需要帮助如何在代码中获得对spring启动的事务的引用,以便我能够以编程方式处理事务

您首先必须注入
org.springframework.transaction.PlatformTransactionManager
-它与所有其他bean一样是一个普通bean:

@Resource
private PlatformTransactionManager transactionManager;
现在,您可以将其与
交易模板
一起使用:

final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallback<String>() {
    @Override
    public Object doInTransaction(TransactionStatus status) {
        transactionManager.rollback(status);
        return ":-(";
    }
});
如果从
@Transactional
方法抛出
运行时异常
,它将自动回滚该事务。否则它将被提交

请注意,这并不意味着JMS和数据库在同一事务上工作!当您抛出异常时,JMS代理将尝试重新传递消息,但是在提交DB事务后,代理很可能会失败。如果您需要100%确保JMS和DB更新都是原子的,那么您需要分布式事务管理器

Spring使用
PlatformTransactionManager
抽象底层事务管理器
在运行时,我们可以注入特定于平台的事务管理器,如下图所示

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

  • 使用接口
    平台事务管理器
    :我们必须显式创建一个
    事务定义
    事务状态
    对象
  • 例如:

           @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;
              }
    
  • 使用类
    交易模板
  • 我们不必显式创建
    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
       }
     });
    }
    
    @Resource
    私有事务模板TransactionTemplate;
    公共void deleteUser(最终int-uid){
    transactionTemplate.execute(新建TransactionCallbackWithoutResult(){
    受保护的void doInTransactionWithoutResult(TransactionStatus paramTransactionStatus){
    试一试{
    //声明
    }捕获(例外e){
    //使用此选项可在出现异常时回滚异常
    paramTransactionStatus.setRollbackOnly();
    }
    }
    });
    }
    公共int插入器(最终用户){
    //如果返回某些结果,请使用TransactionCallback处理程序
    返回transactionTemplate.execute(新建TransactionCallback(){
    公共整数doInTransaction(TransactionStatus参数TransactionStatus){
    //声明
    }
    });
    }
    
    这是否会将消息放回队列?i、 e.队列是否在事务范围内?我是否可以直接使用transactionManager而不使用TransactionTemplate?@user1166503:这有点复杂(理论上)-在默认配置中,会发生以下情况:JMS tx start、DB tx start、DB tx commit、JMS tx commit。若在第3步和第4步之间发生了什么,JMS tx将回滚,但DB已经提交。这是一个问题,因为数据被持久化,但消息将被放回队列。/是的,您可以直接使用
    PlatformTransactionManager
    ,但这有点不方便,模板试图简化它。这有帮助,但仍然不确定您提供的事务回滚代码将如何添加到onMessage()方法中?该方法具有@Transactional注释和编程事务。@user1166503:第一个代码段创建一个新的DB事务并回滚。后者将同时回滚,因为异常会转义
    onMessage
    (准确地说,您还必须添加自定义,因为Spring会吞下JMS
    onMessage()
    异常。我使用第一种方法,注意到一些异常会使连接处于错误状态。因此,以下使用池中该连接的请求会引发错误。除了回滚之外,还有什么其他要做的吗?
    @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
       }
     });
    }