【问题标题】:Making a method transactional in Spring在 Spring 中使方法具有事务性
【发布时间】:2018-02-15 13:56:49
【问题描述】:

我使用休眠作为 JPA 提供程序

@RestController
public class RestController {
    private final TestService testService;

    @PostMapping(value = "/file/{entityId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void test(@PathVariable @NotNull UUID entityId) {
        testService.delete(entityId);
    }
}

class TestService {
    @AutoWired
    EntityRepository repo; // <- Crud repository from Spring Data

    public void delete(UUID id2){
        //if row not exists with id == id2 
            throw NoFoundException
        // else
            //remove from database using repo.
    }
}

以及如何解决以下情况:

  1. “如果行不存在且 id == id2”评估为 false,因为对象实际上存在。
  2. 其他线程删除了该行。
  3. "remove from database using repo"

【问题讨论】:

    标签: spring hibernate spring-boot spring-data


    【解决方案1】:

    您可以在您的服务方法上使用@Transactional,以确保您的数据库操作在事务中运行。默认情况下,如果在带注释的方法中抛出未经检查的异常,则可以回滚事务。您还可以使用@Transactional的rollbackFor 参数指定要回滚的异常

    【讨论】:

      【解决方案2】:

      不知道为什么你有一个基本上与 SimpleJpaRepository 删除方法完全相同的删除方法,所以对于初学者,我会将你的代码更改为

      repo.delete(entityId)
      

      并摆脱测试服务。

      如果您担心在没有要删除的数据时出现 EmptyResultDataAccessException,请捕获异常并忽略它,或者对正在执行删除的任何其他操作使用悲观锁定,如解释 here

      【讨论】:

        【解决方案3】:

        您可以为您的服务方法 delete(UUID id2) 使用注解 @Transaction。@Transaction 的默认传播是 Propagation.REQUIRED 这意味着如果您获得现有事务,它将继续该事务,如果您没有现有事务,则继续将为您创建一个。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-01-19
          • 1970-01-01
          • 2011-05-19
          • 1970-01-01
          • 2012-12-24
          • 2018-06-21
          • 2018-03-09
          相关资源
          最近更新 更多