EJB TimerService Entity не может загрузить старое значение - PullRequest
0 голосов
/ 13 апреля 2020

Похоже, когда я запускаю транзакцию, используя TimerService. Поскольку я устанавливаю значение в entity без сохранения и использую entity = dao.findById, он загружает сущность с новым значением, которое я установил выше, вместо старого. Вот оно: Начало транзакции в PaymentBean

@ApplicationScoped
public class PaymentBean {
    public Response createSendMoneyOrder(Request request) {
        Order order = persistNewOrder();
    {
}

. По некоторым причинам, здесь необходимо повторить попытку заказа, используя TimerService

@ApplicationScoped
public class FirstPendingAuthorizationTimerBean {
    @Inject
    @PendingAuthorization
    private Instance<TimerService> timerService;

    public Timer startTimer(PendingOrderInfo pendingOrderInfo) {
        int timeoutSecs = config.get(3);
        Timer timer = timerService.get().createTimer(timeoutSecs * 1000L, pendingOrderInfo);
        return timer; // in milliseconds
    }

    public void retryAuth(@Observes @PendingAuthorization TimeoutEvent event) {
        if (event.getInfo() instanceof AuthenticationPendingOrderInfo) {
            UUID orderUUID = ((pendingOrderInfo) event.getInfo()).getOrderUuid();
            paymentBean.retryOrder(orderUUID);
        }
    }
}

После повторной попытки я установил значение для сущности заказа и сохранил ее.

private Order handleRetryResponse (Order order) {
    //here order is in state `AUTHORIZED`, then I set it to SUCCESSFUL
    order.setState("SUCCESSFUL")

    //try to look up old order to compare some fields
    Order oldOrder = order.findById(order.getUUID);

    //here oldOrder has state = SUCCESSFUL
}

Вы можете видеть, когда я загружаю старый ордер, состояние становится УСПЕШНЫМ без вызова dao.persist. Для счастливого случая мне не нужен таймер, чтобы повторить попытку, и он работает как ожидалось Это означает, что при загрузке oldOrder значение AUTHORIZED вместо SUCCESSFUL. Только транзакция начинается с таймера в этой ситуации.

Я пробовал это решение, и оно работает: добавьте @Transactional(Transactional.TxType.NOT_SUPPORTED) при методе retryAuth

@ApplicationScoped
public class FirstPendingAuthorizationTimerBean {
    ....
    //My solution
    @Transactional(Transactional.TxType.NOT_SUPPORTED)
    public void retryAuth(@Observes @PendingAuthorization TimeoutEvent event) {
       ...
    }
}

с началом новой транзакции (NOT_SUPPORTED), я Можно загрузить старый заказ со старым значением. Дело в том, что я не понимаю, почему это так работает. Может ли кто-нибудь помочь мне зажечь свет? Благодаря.

...