gpt4 book ai didi

java - 事务如何真正工作 - 简单用例(Spring Boot)?

转载 作者:行者123 更新时间:2023-12-02 10:55:59 25 4
gpt4 key购买 nike

我试图了解我的交易行为是否正确。我在 Spring Boot 上使用 PostgreSQL 构建了一个小型 REST API。

案例是“保留” - 传入请求应该找到某个实体并将其状态设置为“保留”。必须防止的是两个请求返回相同的实体。

目前我正在将整个端点处理程序包装在一个事务中(如下)。据我所知,系统基本上会制作当前状态的快照,然后第一个请求将修改表。

问题是,当第二个请求进来时,第一个请求仍在事务内,会发生什么?我需要 find() 查询将等到第一个事务结束然后继续。至少在理论上,它会像这样工作吗?

@Transactional
@RequestMapping(value = "/newTour", method = RequestMethod.GET, headers = "Accept=application/xml",
consumes = "application/xml", produces = "application/xml")
public @ResponseBody ResponseEntity<?> addTourReservation(@RequestBody PartialTourUpdate partialUpdate) {


try{
List<Tour> tours = tourRepo.findFirstPessimisticByTourTypeInAndStatusOrderByPriorityDesc(partialUpdate.getTourType(), Tour.STATUS_OPEN);
if (tours != null && tours.size() > 0) {
Tour tour = tours.get(0);
tour.setReservationID(partialUpdate.getReservationID());
tour.setStatus(Tour.STATUS_TO_RESERVE);
tourRepo.save(tour);
orderRepo.updateReservationStatus(true, tour.getTourID());
return new ResponseEntity<Tour>(tour, HttpStatus.CREATED);
} else {
rM.setValue(ResultMessage.ErrorCode.LOS_NOT_FOUND);
rM.log();
return new ResponseEntity<ResultMessage>(rM, HttpStatus.OK);
}


} catch (Exception e)
{
rM.setValue(ResultMessage.ErrorCode.LOS_UNKNOWN);
rM.log();
return new ResponseEntity<ResultMessage>(rM, HttpStatus.OK);
}

最佳答案

锁定一行进行更新以防止并发事务读取该行意味着排他锁。

使用 JPA,这是通过 PESSIMISTIC_WRITE 实现的锁定

您需要使用

注释您的存储库方法
 @Lock(LockModeType.PESSIMISTIC_WRITE)

请注意,这将跨越整个 tour 表上的锁,防止任何并发事务读取任何行,这可能意味着重负载下的线程争用问题。

另一种方法可以是选择所有可用的游览,并在列表中保留一个随机选择的游览,并预先使用 entityManager.lock(tour, LockModeType.PESSIMITIC_FORCE_INCREMENT 锁定它(仅锁定它,而不是整个表) )(实体必须有一个@Version属性),如果更新触发异常(如果另一个事务已经保留它),只需选择另一个并尝试更新它。

但是,最好的方法仍然是让数据库处理并发问题,并使用单个 SQL(或 HQL)更新查询来预订“游览”(您的方法中没有业务逻辑,因此您不需要检索并在更新实体之前对其进行操作)。

关于java - 事务如何真正工作 - 简单用例(Spring Boot)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51740974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com