add saga rollback

This commit is contained in:
kimscott
2020-02-10 13:34:44 +09:00
parent afa1b047fe
commit 4c7c3d3345
4 changed files with 62 additions and 6 deletions

View File

@@ -28,7 +28,7 @@ public class Application {
product.setImageUrl("https://github.githubassets.com/images/modules/profile/profile-joined-github.png");
product.setName(p);
product.setPrice(i*10000);
product.setStock(i*1000000);
product.setStock(i*10);
product.setImageUrl("/goods/img/"+p+".jpg");
// 상품 디테일 추가 - 양방향 관계

View File

@@ -1,6 +1,7 @@
package com.example.template;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,7 +49,14 @@ public class ProductController {
@PatchMapping("/product/{productId}")
@HystrixCommand(fallbackMethod = "certifyFallBack")
@HystrixCommand(
fallbackMethod = "certifyFallBack",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), // 기본 타임아웃
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), // 서킷브레이커가 작하게될 에러 퍼센트
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"), // 서킷브레이커가 열리기 위한 최소 요청조 (10초간 19번이 실패해도 서킷은 오픈 안됨)
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000") } // 서킷브래이커가 열렸을때 얼마나 유지할지
)
ResponseEntity<String> fakeProductPatch(@PathVariable(value = "productId") Long productId, @RequestBody String data) {
count++;

View File

@@ -0,0 +1,36 @@
package com.example.template;
public class ProductOutOfStock extends AbstractEvent {
private String stateMessage = "재고량 바닥";
private Long productId;
private Long orderId;
public ProductOutOfStock(){
super();
}
public String getStateMessage() {
return stateMessage;
}
public void setStateMessage(String stateMessage) {
this.stateMessage = stateMessage;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
}

View File

@@ -37,7 +37,17 @@ public class ProductService {
Product product = productOptional.get();
product.setStock(product.getStock() - orderPlaced.getQuantity());
productRepository.save(product);
if( product.getStock() < 0 ){
System.out.println("productOutOfStock 이벤트 발생");
ProductOutOfStock productOutOfStock = new ProductOutOfStock();
productOutOfStock.setProductId(orderPlaced.getProductId());
productOutOfStock.setOrderId(orderPlaced.getOrderId());
productOutOfStock.publish();
}else{
productRepository.save(product);
}
}
@@ -47,9 +57,11 @@ public class ProductService {
if( orderPlaced.getEventType().equals(OrderCancelled.class.getSimpleName())){
Optional<Product> productOptional = productRepository.findById(orderPlaced.getProductId());
Product product = productOptional.get();
product.setStock(product.getStock() + orderPlaced.getQuantity());
productRepository.save(product);
// productOutOfStock 상황이 아닐때만 재고량을 늘린다.
if( product.getStock() - orderPlaced.getQuantity() > 0 ){
product.setStock(product.getStock() + orderPlaced.getQuantity());
productRepository.save(product);
}
}
}catch (Exception e){