【问题标题】:Spring boot transaction keeps running after commiting in async methodSpring Boot 事务在异步方法中提交后继续运行
【发布时间】:2022-02-07 01:44:18
【问题描述】:

我有这种情况:

@Transactional
public void setStopped(Machine machine)
{
    machine.setStatus(StatusType.STOPPED);
    machineRepository.saveAndFlush(machine);
}

@Transactional
public void setRunningAndAvailable(Machine machine)
{
    machine.setStatus(StatusType.RUNNING);
    machine.setAvailable(true);
    machineRepository.saveAndFlush(machine);
}

@Async
public void restart(Machine machine, int bound, int sec)
{
    try
    {
        if(machine.getStatus().equals(StatusType.RUNNING))
        {
            Random random = new Random();
            int number = random.nextInt(bound) * 1000;
            Thread.sleep((sec * 1000L) + number);

            setStopped(machine);

            number = random.nextInt(bound) * 1000;
            Thread.sleep((sec * 1000L) + number);

            setRunningAndAvailable(machine);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

我不断收到以下错误:

org.springframework.orm.ObjectOptimisticLockingFailureException

Caused by: 
org.hibernate.StaleObjectStateException: Row was updated or deleted by another 
transaction (or unsaved-value mapping was incorrect)

第一种方法结束后数据库没有更新 (setStopped),当我第二次尝试 saveAndFlush (setRunningAndAvailable) 时出现这些错误,这让我相信不知何故第一笔交易是仍在进行中。

我尝试做@Transactional(propagation = Propagation.NESTED)@Transactional(propagation = Propagation.REQUIRES_NEW),但我得到了同样的错误。

我不知道为什么会一直这样,如果有人可以帮助我,我将不胜感激。

【问题讨论】:

    标签: java mysql spring asynchronous transactions


    【解决方案1】:

    您需要知道@Transactional 与AOP 一起使用,因此行为(事务的创建和提交)是在进入您的方法之前和返回之后添加的。

    主要问题是您从同一个 bean so you are not traversing the proxy layer of the bean 调用方法,而不是触发 @Transactional 行为..

    您需要在另一个类中移动带注释的方法,并将该 bean 注入您的类中。

    【讨论】:

    • 我刚刚尝试实施您的解决方案,但没有奏效。我可能做错了什么。我创建了一个用@Service 注释的新类,并添加了这两个方法并用@Transactional 注释它们。然后,我在原始类中添加了该类(使用注入)并使用了它的方法。我做错了吗?
    • 传入参数的“机器”是否已经存在于数据库中?如果是这种情况,则在每个 Transactional 方法的开头查找/附加实体会更清楚(例如使用 getByID)。我认为你的错误是你正在改变一个分离实体的状态。 (顺便说一句,在您的情况下,您可以使用 save() 而不是 saveAndFlush(),因为会话将在事务结束时自动刷新,所以它是多余的)
    猜你喜欢
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 2021-07-15
    • 2019-11-25
    • 1970-01-01
    相关资源
    最近更新 更多