我正在Spring和Hibernate工作。我有一个需要在其中添加数字来更新特定字段的要求。由于多个线程可以同时执行它,因此在更新时,我会使用旧值检查字段值。因此,如果未进行任何更新,则意味着它已被其他线程递增,并且我们触发了重试。公司服务public Company getAndIncrementRequestId(final int companyId, int retry) throws Exception { Optional<Company> companyOptional = companyRepository.findById(companyId); if (!companyOptional.isPresent()) { throw new EntityNotFoundException("Company not found for given id" + companyId); } Company company = companyOptional.get(); int oldRequestId = company.getRequestId(); int requestId; if (oldRequestId == Integer.MAX_VALUE) { requestId = 1; } else { requestId = oldRequestId + 1; } company.setRequestId(requestId); //--------------------------> PROBLEM int result = companyRepository.updateRequestId(companyId, requestId, oldRequestId); if (result == 0) { if (retry < 0) { throw new Exception("Unable to get requestId"); } LOG.warn("Retrying since there was some update on requestId by some other thread"); try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { LOG.warn("Unexpected InterruptException occurred while trying to get requestId"); } return getAndIncrementRequestId(companyId, retry - 1); } return company;}公司资料库@Transactionalpublic interface CompanyRepository extends CrudRepository<Company, Integer> { Optional<Company> findById(String id); @Modifying(clearAutomatically = true) @Query("update Company c set c.requestId = :requestId WHERE c.id = :companyId AND c.requestId = :oldRequestId") int updateRequestId(@Param("companyId") Integer companyId, @Param("requestId") Integer requestId,@Param("oldRequestId") Integer oldRequestId);}但是,以上代码在Service中将触发两个休眠更新,其中一个将requestId设置为最新的requestId,另一个将实际更新。将show-sql设置为true后,可以在日志中观察到两个查询。但是如果这条线,company.setRequestId(requestId);在companyRepository.updateRequestId()正常运行后向下移动。
添加回答
举报
0/150
提交
取消