当前位置: 首页 > 知识库问答 >
问题:

Spring对异步事务方法的catch错误进行操作

公孙鸿才
2023-03-14

我已经阅读了Spring@Transactional-Isolation,propagation中的指令

但是我不明白我解释的这个特性是如何产生的:我有一个异步方法,像这样

@Transactional(timeout = TRANSACTION_TIMEOUT, propagation = Propagation.REQUIRES_NEW)
@Async("asyncImportExecutor")
public void startBeggin(Long id, String jwtToken) {

    try {
        . . .

    } catch (Exception e) {
        log.error("Error: " + e);

        utilsService.setFlag(id, 0L); // every type of error, revert flag to 0
    }
 public void setFlag(Long id, Long state) {

    /* recover data from repository */
    Processo processo = getRepo().getOne(id);
    processo.setAvanzamento(state);
    getRepo().saveAndFlush(processo);
}

此方法(setFlag)在调用异步方法之前通过1L调用一次

getService().setFlag(id, (long) 1);

并且在异步方法中的所有操作结束时传递零

getService().setFlag(id, (long) 0);

但是,如果异步方法因某些问题而失败,则catch分支中的调用将失败,因为

org.springframework.orm.jpa.JpaSystemException: Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit

且标志保持为1。

所以,我希望我是清楚的,但是...我如何确保,在异步方法(startBeggin)中的操作回滚之后,在该操作之间发生的任何异常时,在该对象上设置该值?

我如何设置(或更新)一个对象上的字段,在一个事务(失败)的回溯上?

共有1个答案

席弘图
2023-03-14

这种方法很大程度上取决于您想要在这里完成什么。但试图给出一个简单的答案:

事务已标记为仅回滚

意味着数据库资源所做的所有更改都将在事务结束时回滚(而不是持久化)->在您的情况下是在startBeggin方法结束时。

您还应该记住@transactional何时工作:

https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations

 类似资料:
  • 场景是,我有一个带有spring批处理作业的spring启动应用程序。我正在尝试使用和使批处理作业异步,然后将此taskExecutor分配给JobLauncher。更改后,作业会异步运行,但我在持久化或更新数据库方面遇到了问题: 谢谢你的帮助!

  • 本文向大家介绍C#异步执行任务的方法,包括了C#异步执行任务的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#异步执行任务的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 我正在从非事务类try块(由另一个EJB类调用)调用事务方法a,该块将引发RuntimeException 然后在catch块中,事务方法b将处理exp。 令人惊讶的是,我必须用“REQUIRES\u NEW”注释方法B,否则程序将出现“Transaction is not active”异常。(stacktrace与此类似) 这是否是因为方法A的事务(标记为RuntimeException的回滚

  • 我正在使用的应用程序将按以下顺序使用2个REST web服务: 1) 计数记录-了解特定时间范围内的记录数。 2)获取记录——一旦我们有了记录的数量,我们就需要调用这项服务。但是这项服务有一个门槛来一次性获取10K记录。假设第一个服务在特定的时间间隔内告诉我,它有100K的记录,那么我需要以分页方式调用第二个网络服务10次,考虑到它的阈值是一次10K的。 因此,如果我将进行10次同步调用,我的应用

  • 本文向大家介绍async/await让异步操作同步执行的方法详解,包括了async/await让异步操作同步执行的方法详解的使用技巧和注意事项,需要的朋友参考一下 一.前言 我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的

  • 我有100个对象,我想将其保存到数据库。 我对“名称”列有uniq约束,如果我尝试用某个名称保存2个对象,就会出现异常。 我需要保存99个对象(唯一的名称),并跳过一个重复的名称对象。但是如果我尝试插入dublicate,我会得到一个异常,事务回滚所有对象。我改变我的刀savee()方法: Propagation.REQUIRES_NEW - 在每个对象上启动内部事务,并且仅对rollbak对象进