lock refunds against duplicates

This commit is contained in:
2026-04-15 15:48:17 -06:00
parent 5a6a63eef6
commit f95e1e310d
4 changed files with 17 additions and 2 deletions

View File

@@ -1,14 +1,23 @@
package com.petshop.backend.repository;
import com.petshop.backend.entity.Refund;
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface RefundRepository extends JpaRepository<Refund, Long> {
List<Refund> findByCustomerIdOrderByCreatedAtDesc(Long customerId);
List<Refund> findAllByOrderByCreatedAtDesc();
List<Refund> findBySaleId(Long saleId);
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT r FROM Refund r WHERE r.id = :id")
Optional<Refund> findByIdForUpdate(@Param("id") Long id);
}

View File

@@ -1,10 +1,12 @@
package com.petshop.backend.repository;
import com.petshop.backend.entity.Sale;
import jakarta.persistence.LockModeType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.time.LocalDateTime;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@@ -42,5 +44,9 @@ public interface SaleRepository extends JpaRepository<Sale, Long> {
List<Sale> findByOriginalSaleSaleId(Long originalSaleId);
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT s FROM Sale s WHERE s.saleId = :id")
Optional<Sale> findByIdForUpdate(@Param("id") Long id);
Optional<Sale> findByCartCartId(Long cartId);
}

View File

@@ -112,7 +112,7 @@ public class RefundService {
@Transactional
public RefundResponse updateRefundStatus(Long id, String status) {
Refund refund = refundRepository.findById(id)
Refund refund = refundRepository.findByIdForUpdate(id)
.orElseThrow(() -> new ResourceNotFoundException("Refund not found"));
Refund.RefundStatus newStatus;

View File

@@ -107,7 +107,7 @@ public class SaleService {
}
if (sale.getIsRefund() && request.getOriginalSaleId() != null) {
Sale originalSale = saleRepository.findById(request.getOriginalSaleId())
Sale originalSale = saleRepository.findByIdForUpdate(request.getOriginalSaleId())
.orElseThrow(() -> new ResourceNotFoundException("Original sale not found with id: " + request.getOriginalSaleId()));
sale.setOriginalSale(originalSale);
}