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

发布于 2024-12-29 14:13:27 字数 547 浏览 0 评论 0原文

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

I want to use spring programmatic transaction in JMS application that receive a message from queue. At the same time, I want to include the queue in transactional scope.

Using Spring DefaultMessageListnereContainer and injecting transaction manager in it. However, not sure how will I get the reference of this transaction to programmatically commit or rollback?


I read and understand "processing messages within transactions" here
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/jms.html#jms-tx-participation

My 2 requirements are -
1) XA transactions hence injecting JtaTransactionManager,
2) Use programmatic transactions - here I need help how to get reference to the transaction started by spring in the code so that I can programmatically handle transactions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

农村范ル 2025-01-05 14:13:27

你首先必须注入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!");
}

如果您从 @Transactional 方法抛出 RuntimeException,它将自动回滚该事务。否则就会犯。

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

You first have to inject org.springframework.transaction.PlatformTransactionManager - it is an ordinary bean like all the others:

@Resource
private PlatformTransactionManager transactionManager;

Now you can use it together with TransactionTemplate:

final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallback<String>() {
    @Override
    public Object doInTransaction(TransactionStatus status) {
        transactionManager.rollback(status);
        return ":-(";
    }
});

Quite a lot of code, so here is how you should do this:

@Transactional
public void onMessage(Message message) {
    //rollback:
    throw new HoustonException("We've got a problem!");
}

If you throw a RuntimeException from @Transactional method, it will automatically rollback that transaction. Otherwise it will be committed.

Note that this doesn't mean that JMS and database is working on the same transaction! When you throw an exception the JMS broker will try to redeliver the message, however chances are that the broker will fail after the DB transaction was committed. If you need to be 100% sure that both JMS and DB updates are atomic, you need distributed transaction manager.

无畏 2025-01-05 14:13:27

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

输入图片这里的描述

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

  1. 使用接口PlatformTransactionManager:我们有明确地创建一个 TransactionDefinitionTransactionStatus 对象。

例如:

       @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

我们不必显式创建 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
   }
 });
}

Spring abstracts underlying transaction manger using PlatformTransactionManager.
At runtime we can inject platform specific transaction manager shown in the following image.

enter image description here

We can get Transaction Manager reference in spring programmatic approach the following two ways:

  1. Using interface PlatformTransactionManager : We have to explicitly create a TransactionDefinition and TransactionStatus object.

For Example:

       @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. Using class TransactionTemplate :

We do not have to explicitly create a TransactionDefinition and TransactionStatus object. The TransactionTemplate provides a callback method called execute where we can add our business logic that we want to wrap in a transaction.

There are two types of callback methods that we can use to wrap our code i.e TransactionCallbackWithoutResult and TransactionCallback(T)

For Example:

@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
   }
 });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文