Skip to content

Commit

Permalink
Implement requestId
Browse files Browse the repository at this point in the history
  • Loading branch information
leung018 committed Dec 11, 2024
1 parent 0a85981 commit c51cbd8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.leungcheng.spring_simple_backend.domain.order;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
Expand All @@ -11,11 +12,15 @@ public class Order {
private String buyerUserId;
private PurchaseItems purchaseItems;

@Column(unique = true)
private String requestId;

private Order() {}

Order(String buyerUserId, PurchaseItems purchaseItems) {
Order(String buyerUserId, PurchaseItems purchaseItems, String requestId) {
this.buyerUserId = buyerUserId;
this.purchaseItems = purchaseItems;
this.requestId = requestId;
}

public String getId() {
Expand All @@ -29,4 +34,8 @@ public String getBuyerUserId() {
public PurchaseItems getPurchaseItems() {
return purchaseItems;
}

public String getRequestId() {
return requestId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

import org.springframework.data.repository.CrudRepository;

public interface OrderRepository extends CrudRepository<Order, String> {}
import java.util.Optional;

public interface OrderRepository extends CrudRepository<Order, String> {
Optional<Order> findByRequestId(String requestId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public CreateOrderException(String message) {
@Retryable(noRetryFor = CreateOrderException.class)
@Transactional(isolation = Isolation.SERIALIZABLE)
public Order createOrder(String buyerUserId, PurchaseItems purchaseItems, String requestId) {
Optional<Order> order = orderRepository.findByRequestId(requestId);
if (order.isPresent()) {
return order.get();
}

User buyer =
getUser(buyerUserId).orElseThrow(() -> new CreateOrderException("Buyer does not exist"));

Expand All @@ -39,7 +44,7 @@ public Order createOrder(String buyerUserId, PurchaseItems purchaseItems, String
}
saveNewBalance(buyer, buyer.getBalance().subtract(totalCost));

return addNewOrder(buyerUserId, purchaseItems);
return addNewOrder(buyerUserId, purchaseItems, requestId);
}

private Optional<User> getUser(String userId) {
Expand All @@ -51,8 +56,8 @@ private void saveNewBalance(User buyer, BigDecimal newBalance) {
userRepository.save(updatedBuyer);
}

private Order addNewOrder(String buyerUserId, PurchaseItems purchaseItems) {
Order order = new Order(buyerUserId, purchaseItems);
private Order addNewOrder(String buyerUserId, PurchaseItems purchaseItems, String requestId) {
Order order = new Order(buyerUserId, purchaseItems, requestId);
return orderRepository.save(order);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,32 @@ void shouldEachCreatedOrderHasDifferentId() {
PurchaseItems purchaseItems = new PurchaseItems();
purchaseItems.setPurchaseItem(product.getId(), 1);

Order order1 = createOrder(buyer.getId(), purchaseItems);
Order order2 = createOrder(buyer.getId(), purchaseItems);
Order order1 = createOrder(buyer.getId(), purchaseItems, "request-01");
Order order2 = createOrder(buyer.getId(), purchaseItems, "request-02");

assertNotEquals(order1.getId(), order2.getId());
}

@Test
void shouldOneOrderBeingCreatedOnly_IfCreateOrderWithSameRequestIdTwice() {
User buyer = randomUsernameUserBuilder().balance(new BigDecimal(10)).build();
userRepository.save(buyer);

Product product = productBuilder().quantity(5).price(new BigDecimal(1)).build();
productRepository.save(product);

PurchaseItems purchaseItems = new PurchaseItems();
purchaseItems.setPurchaseItem(product.getId(), 1);

Order order1 = createOrder(buyer.getId(), purchaseItems, "request_id");
Order order2 = createOrder(buyer.getId(), purchaseItems, "request_id");

assertOrderEquals(order2, order1);
assertEquals(4, productRepository.findById(product.getId()).orElseThrow().getQuantity());
assertBigDecimalEquals(
new BigDecimal(9), userRepository.findById(buyer.getId()).orElseThrow().getBalance());
}

@Test
void shouldAutoRetry_WhenOneThreadMayFailJustDueToRacing() {
User seller = randomUsernameUserBuilder().balance(new BigDecimal(999)).build();
Expand All @@ -245,8 +265,8 @@ void shouldAutoRetry_WhenOneThreadMayFailJustDueToRacing() {
purchaseItems.setPurchaseItem(product.getId(), 1);

// 2 threads try to buy the same product at the same time
Thread thread1 = new Thread(() -> createOrder(buyer.getId(), purchaseItems));
Thread thread2 = new Thread(() -> createOrder(buyer.getId(), purchaseItems));
Thread thread1 = new Thread(() -> createOrder(buyer.getId(), purchaseItems, "request-01"));
Thread thread2 = new Thread(() -> createOrder(buyer.getId(), purchaseItems, "request-02"));

thread1.start();
thread2.start();
Expand All @@ -265,11 +285,16 @@ private Order createOrder(String buyerUserId, PurchaseItems purchaseItems) {
return orderService.createOrder(buyerUserId, purchaseItems, "dummy_request_id");
}

private Order createOrder(String buyerUserId, PurchaseItems purchaseItems, String requestId) {
return orderService.createOrder(buyerUserId, purchaseItems, requestId);
}

private void assertOrderEquals(Order expected, Order actual) {
assertEquals(expected.getId(), actual.getId());
assertEquals(expected.getBuyerUserId(), actual.getBuyerUserId());
assertEquals(
expected.getPurchaseItems().getProductIdToQuantity(),
actual.getPurchaseItems().getProductIdToQuantity());
assertEquals(expected.getRequestId(), actual.getRequestId());
}
}

0 comments on commit c51cbd8

Please sign in to comment.