java - 如何使用@Transactional读取spring方法中保存的实例

标签 java spring-boot transactions rollback

我使用 @Transactional 注释来进行回滚,我在 Spring-Boot 应用程序中添加了 Controller 方法,因此只有在一切都发生且没有任何错误的情况下才会进行保存,这就是我添加注释的方式:

    @PostMapping(value = "/add/people")
    @Transactional
    public ResponseEntity<?> addGroundToPerson(@RequestParam("ground") String newGround, @RequestParam("person") String person {
        try {
             personService.addPerson(person, ground);
             Ground addedGround = groundService.addGround(pnewGround);
        } catch (NoSuchElementException e) {
            return new ResponseEntity<>(new CustomErrorType(e.getMessage()), HttpStatus.NOT_IMPLEMENTED);
    }

addPersonToGround 正在将该人及其地址保存到数据库中。

addGround 正在使用该人的引用将新地面保存在数据库中,并且地面本身有一个地址。

我的服务方法失败:

public void registerAddress(HasAddress hasAddress) throws NoSuchElementException {

        Address address = hasAddress.getAddress());
        State state = address.getState();

        //here's where I'm getting the error
        State dbState = searchState(state); //stateRepository.getStateByName();

        address.setState(state);
        hasAddress.setAddress(address);

        addressRepository.save(address);
    }

RegisterAddress 被调用了两次,第一次工作正常,但因为我第一次保存了,所以第二次不起作用。 (请记住,我的代码比这个大得多,我不能直接取消保存,我已经尝试过了,相信我)。

我尝试将 @Transactional 放入服务层,但它向我发送了此错误:

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance

当我只保存对象时,它工作正常,但当我必须在保存后获取对象时,它工作正常。这就是我的问题,我最好的例子是这样的:

  1. 每个人都有一个地址,其中包含州/省/自治区。
  2. 如果每个地址的状态相同,我想重复使用该状态。
  3. 我注册一个人,它注册一个新地址(有时使用数据库中已存在的状态)。
  4. 我尝试注册地面,当我尝试让该状态重用它时,出现错误:

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

我认为发生这种情况是因为当我第一次“保存”对象时它不会提交,因此它保持 transient ,而我只是无法获取 transient 对象。我试图制作所有逻辑并在其末尾保存,或者如果发生一些异常则回滚,但由于注释,我收到了该错误。

最佳答案

这件事有很多问题。首先,您已将 @Transactional 放入 Controller 层而不是服务层。您的方法的逻辑也应该位于服务层。这个 - rollbackFor = Exception.class 并不是真正必要的,因为 Spring 默认在所有用 注释的方法上放置 rollbackFor = { RuntimeException.class, Error.class } @事务性。现在您收到上述异常的原因是因为您在其中放置了一个 try/catch block 。仅当抛出异常时,Spring 的事务才会被标记为回滚,无论异常是否被捕获。您必须删除 try/catch 或找到一种在事务之外执行此操作的方法。

关于java - 如何使用@Transactional读取spring方法中保存的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60514027/

相关文章:

java - 如何访问fitnesse页面的内容?

带有 "..."数组的 Java 主要方法?

hibernate - Spring Boot 2/Kotlin/JDK9 - 由 : java. lang.ClassNotFoundException : javax. transaction.SystemException 引起

spring - spring boot需要WAS(Websphere Application Server)吗?

jakarta-ee - 跨 WebLogic WorkManager 线程共享事务(使用 CommonJ)

java - 如何隔离 Apache Ignite 中的事务

java - Spoj NZEC 错误

java - 如何创建 react 性 'intermediate subscriber' ?如何将所有 Flux<T> 部分和它们的处理结果在链中进一步组合(转换为 Mono<R>)?

spring-boot - 在 Spring Data 中添加新的 DB 支持

java - Spring @Transactional 和继承