如何创建一个JPA存储库Transactional而另一个没有?

时间:2016-05-13 09:52:58

标签: java spring hibernate transactions spring-data-jpa

我有方法,我正在尝试更改某个实体,同样在此方法中我想保存交易信息。 当发生任何异常时,我想回滚保存实体但仍希望保存事务。 那么如何为实体事务创建一个存储库而不为事务创建存储库呢?

存储库中的代码

@Override
@Transactional(noRollbackFor=NotEnoughAmountInAccountException.class)
<T extends Transaction> T save(T transaction);

但它没有帮助。 保存最终区块中的交易。

更新

我使用AOP解决了它。我在方面建议中创建了Transaction对象,并将其保存在JPA事务中。

2 个答案:

答案 0 :(得分:0)

Do it in a new @Transactional

@Transactional(propagation=Propagation.REQUIRES_NEW)
<T extends Transaction> T save(T transaction);

This will save your transaction element even if the other @Transactional gets rolled back

答案 1 :(得分:0)

我使用AOP解决了它。我在方面建议中创建了Transaction对象,并将其保存在JPA事务中。

这是@Transactional方法

@SaveTransaction
@Transactional
public synchronized Transaction move(@NonNull String accountName, @NonNull String destinationName, @NonNull BigDecimal amount, String comment) {
    checkAmountIsPositive(amount);

    Account donor = getAccount(accountName);
    Account acceptor = getAccount(destinationName);

    if (!isEnoughAmount(accountName, amount)) throw new NotEnoughAmountInAccountException();

    BigDecimal newDonorAmount = donor.getAmount().add(amount.negate());
    BigDecimal newAcceptorAmount = acceptor.getAmount().add(amount);

    donor.setAmount(newDonorAmount);
    acceptor.setAmount(newAcceptorAmount);

    accountRepository.save(donor);
    accountRepository.save(acceptor);

    return null;
}

这是方面建议

@Around("@annotation(com.softjourn.coin.server.aop.annotations.SaveTransaction)")
public Transaction saveTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
    Transaction transaction = prepareTransaction(joinPoint);
    try {
        joinPoint.proceed();
        transaction.setStatus(TransactionStatus.SUCCESS);
        return transaction;
    } catch (Throwable e) {
        transaction.setStatus(TransactionStatus.FAILED);
        transaction.setError(e.getLocalizedMessage());
        throw e;
    } finally {
        transactionRepository.save(transaction);
    }
}

此建议的顺序高于@Transactional的顺序也很重要,因此这个建议将超过交易。 在方面类上设置@Order(100)。 默认情况下,它的订单较小,因此它处于交易状态。