为了账号安全,请及时绑定邮箱和手机立即绑定

事务如何真正工作 - 简单用例(sping boot)?

事务如何真正工作 - 简单用例(sping boot)?

慕仙森 2021-06-27 16:59:53
我试图了解我是否在做正确的交易。我在 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);    }
查看完整描述

2 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

锁定一行以防止并发事务读取它意味着排他锁。

使用 JPA,这是使用PESSIMISTIC_WRITE锁实现的

您需要使用

 @Lock(LockModeType.PESSIMISTIC_WRITE)

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

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

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


查看完整回答
反对 回复 2021-07-07
  • 2 回答
  • 0 关注
  • 128 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信