스프링 사무와 메시지 대기열 배우기
하나.문제 발생:
장면 복원: 인터페이스의 한 방법으로 먼저 주문 상태를 수정한 다음에 메시지 대기열에서 정보를 생산한다. 메시지 대기열의 소비자는 메시지 검측 주문 상태를 얻고 주문 상태가 변경되지 않은 것을 발견한다.
코드:
@Service(orderApi)
public class OrderApiImpl implements OrderApi {
@Resource MqService mqService;
@OrderDao orderDao;
public void push(String orderId) {
// , 1
updateStatus(orderId, 3);
//
mqService.produce(orderId);
}
public viod updateStatus(String orderId, Integer status) {
orderDao.updateStatus(orderId, status);
}
}
문제 발생 원인: orderApi의 모든 방법에는 트랜잭션이 있습니다. 트랜잭션 유형 PROPAGATION_REQUIRED, 따라서push 방법이 데이터에 대한 작업은push 코드가 모두 실행된 후에 제출되며, 사무 제출 전에 메시지 대기열의 메시지가 발생하기 때문에 메시지 대기열에서 소비된 주문서가 데이터베이스에서 조회된 상태는 1이 될 수 있습니다.버그 현상을 더욱 뚜렷하게 하기 위해push 방법의 마지막에 추가할 수 있습니다.
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
이렇게 하면 소비 소식을 발견할 때 주문 상태는 틀림없이 수정되지 않은 것이다. 2.문제 해결:
해결 방안: 데이터를 업데이트할 때 새로운 사물을 만들고 업데이트 코드의 실행이 끝난 후에 데이터베이스 업데이트 업무가 제출되었음을 보증합니다.(메시지 생성 전 데이터베이스 작업이 제출되었는지 확인)
상술한 방안에 따라 내가 먼저 생각한 것은 업데이트 Status 방법의 사무 유형을 직접 수정하는 것이다.이 메서드의 트랜잭션 유형을 PROPAGATION_ 으로 변경합니다.REQUIRES_NEW(현재 트랜잭션이 있는 경우 현재 트랜잭션을 종료합니다).
그러나 이렇게 하는 것은 두 가지 적합하지 않다.
1.updateStaus의 업무 유형을 강제로 수정하여 다른 절차에 영향을 미칠 수 있습니다.
2.작동하지 않습니다. 업데이트 Staus 방법에 새 업무가 없습니다.
두 번째 설명: 스프링 추가 업무는 BeanName AutoProxy Creator를 통해 이루어진 동적 에이전트입니다. 단지 bean 대상에 업무를 추가했을 뿐입니다. 현재 클래스 내부에서 호출하는 방법은 새로운 사물의 생성을 촉발하지 않습니다.
그래서 이상의 시도를 거친 후에 나는 새로운 클래스를 만들었다.
@Service("orderExtApi")
public class OrderExtApiImpl {
@Resource OrderApi orderApi;
public void updateStatusNewPropagation(String orderId) {
orderApi.updateStatus(orderId);
}
}
업데이트StatusNewPropagation 방법에 트랜잭션 추가PROPAGATION_REQUIRES_NEW이 클래스는order Api의 업데이트 Staus 방법에 대한 새로운 사무를 만들기 위해서입니다.
ok, 여기까지 버그가 해결되었습니다.
그러나 코드에 아직도 문제가 존재한다. 데이터베이스에 대한 조작이 제출되었고 생산 메시지에 이상이 발생하면 업무 논리적으로 잘못된 것이다.그래서 메시지의 생성이 완료되었는지 검사해야 한다.
최종 orderApi의 코드는 다음과 같습니다.
@Service(orderApi)
public class OrderApiImpl implements OrderApi {
@Resource MqService mqService;
@Resource OrderDao orderDao;
@Resource OrderExtApiImpl orderExtApi;
public void push(String orderId) {
// , 1
orderExtApi.updateStatusNewPropagation(orderId, 3);
// --produce 1
Response response = mqService.produce(orderId);
if (response.getCode() != 1) {
log.info(" :" + response.getErrorMsg())
// ,
orderExtApi.updateStatusNewPropagation(orderId, 1);
}
}
public viod updateStatus(String orderId, Integer status) {
orderDao.updateStatus(orderId, status);
}
}
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.