This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void handle(Message<String> message) | |
throws RetryableException, DroppableException, DlqableException { | |
try { | |
doStuff(message); | |
} catch (IllegalArgumentException ex) { | |
throw new DlqableException(ex); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public RetryTemplate eventConsumerRetryTemplate(int maxAttempts) { | |
return RetryTemplate.builder() | |
.retryOn(RetryableException.class) | |
.maxAttempts(maxAttempts) | |
.exponentialBackoff(100, 2, 300) | |
.traversingCauses() | |
.build(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void consume(Message<String> message) { | |
try { | |
final EventHandler handler = subscriptionMap.get(event); // Selecting a appropriate handler based on the message | |
processWithRetry(handler, message); | |
} catch (RequeableException e) { | |
failureHandler.reQueue(message, e); | |
} catch (DroppableException e) { | |
failureHandler.dropMessage(message, e); | |
} catch (Exception e) { | |
failureHandler.putOnDlq(message, e); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Transactional | |
public Optional<Order> placeOrder(Long productId, Long userId) { | |
Optional<Product> product = productRepository.findByIdWithWriteLock(productId); | |
product.orElseThrow(() -> new RuntimeException("Invalid product id")); | |
if (product.get().getAvailableUnits() > 0) { | |
productRepository.decrementAvailableUnitsCountBy1(productId); | |
Order newOrder = new Order(userId, productId); | |
orderRepository.save(newOrder); | |
return Optional.of(newOrder); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Query(value = "select * from products where id = ?1 for update", nativeQuery = true) | |
Optional<Product> findByIdWithWriteLock(Long productId); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Query("update products set available_units = available_units - 1 where id = ?1") | |
@Modifying | |
void decrementAvailableUnitsCountBy1(Long productId); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Transactional | |
public Optional<Order> placeOrder(Long productId, Long userId) { | |
Optional<Product> product = productRepository.findById(productId); | |
product.orElseThrow(() -> new RuntimeException("Invalid product id")); | |
if (product.get().getAvailableUnits() > 0) { | |
productRepository.decrementAvailableUnitsCountBy1(productId); | |
Order newOrder = new Order(userId, productId); | |
orderRepository.save(newOrder); | |
return Optional.of(newOrder); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Test | |
void shouldCreateOrder() throws InterruptedException { | |
Product iPhone12 = new Product("iPhone12", 1); | |
productRepository.saveAndFlush(iPhone12); // Insert product with count 1 into DB | |
ExecutorService threadPool = Executors.newFixedThreadPool(10); // Create a threadpool with 10 threads | |
List<Callable<Optional<Order>>> orderRequests = getOrderRequests(iPhone12.getId(), 20); // Create 20 tasks for placing 20 orders | |
List<Future<Optional<Order>>> results = threadPool.invokeAll(orderRequests); // Place those 20 orders simulteanously | |
long successCount = results.stream() // Calculate how many orders got placed successfully |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"level" : "ERROR", | |
"message" : "NullPointerException" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Data | |
@AllArgsConstructor | |
public class StorePresenter { | |
private String id; | |
private final String name; | |
private final String zipCode; | |
private final Double latitude; | |
private final Double longitude; | |
NewerOlder