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

如何使一个JPA存储库具有事务性,而另一个不具有事务性?

郭单鹗
2023-03-14

我有一个方法,我试图改变一些实体,在这个方法中我也想保存交易信息。当发生任何异常时,我想回滚保存实体,但仍然想保存交易。那么如何为实体事务建立一个存储库,而不是为事务建立一个存储库呢?

有存储库的代码

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

但这没有帮助。保存放置在最后一个块中的交易。

使现代化

我用AOP解决了这个问题。我在aspect advice中创建了事务对象,并将其保存在JPA事务之外。

共有2个答案

松铭
2023-03-14

我用AOP解决了这个问题。我在aspect advice中创建了事务对象,并将其保存在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的顺序,这样此建议将超过事务。在aspect类上设置@Order(100)。默认情况下,它的订单较小,因此正在进行交易。

经骁
2023-03-14

在新的事务中执行

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

这将保存您的事务元素,即使另一个事务元素回滚

 类似资料:
  • 问题内容: 关于Spring JPA存储库事务性的1个快速问题。我有未标记为事务性的服务,并调用了Spring JPA存储库方法 它被定义为 问题是它失败,并且“ 没有EntityManager,当前线程没有可用的实际事务- 无法可靠地处理’remove’调用;嵌套异常是javax.persistence.TransactionRequiredException “异常。 好的,我可以通过将服务

  • 关于Spring JPA存储库事务性的1个快速问题。我有一个未标记为事务性的服务,并调用Spring JPA存储库方法 好的,我可以通过标记服务或deleteByEmail(..)来解决它方法作为事务性的,但我就是不明白为什么它现在会崩溃。Spring文档明确指出“存储库实例上的CRUD方法在默认情况下是事务性的。”(http://docs.spring.io/spring-data/jpa/do

  • 本文向大家介绍Spring如何在一个事务中开启另一个事务,包括了Spring如何在一个事务中开启另一个事务的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Spring如何在一个事务中开启另一个事务,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 spring使用@Transactional开启事务,而且该注解使用propagation属

  • 我正在计划一个设计,我将从同一个池中获得两个连接(plocal)。仅在一个连接上启动事务,而不在另一个连接上启动事务。我希望在同一过程中使用这两个数据库连接,并使用非事务连接进行模式调用,使用事务连接进行支持事务的记录级调用。这种方法有效吗?

  • 最近,我注意到Spring Data JDBC,所以我决定在一个新的Spring Boot(2.3.1)应用程序中使用它。在我的用例中,我有一个包含两类表的DB模式: 用于存储应用程序(更复杂的)业务逻辑所使用的实体的表。我使用Spring Data JPA(带有底层Hibernate)来处理它们。 表,用于存储彼此之间没有太多关系的简单数据记录(例如来自外部系统的数据记录)。我决定对它们使用Sp

  • 我正在尝试使用Hibernate保存数据。一切都发生在同一会话中。逻辑如下: 1)开始交易并尝试保存: 2) 如果新记录违反完整性约束,请在外包装方法中捕获异常,打开另一个事务并查询更多数据 问题是当第二个事务执行时query.list它会抛出一个应该与前一个事务链接的异常。 SQLIntegrityConstraintViolationException:ORA-00001:唯一约束 我应该从另