개발 과정에서 버그가 발생했습니다. 버그의 이유는 Spring Transaction이 메시지 대기열보다 늦게 생산 메시지를 제출했기 때문에 메시지 큐가 메시지를 소비 할 때 잘못된 데이터를 얻었 기 때문입니다. 이 기사는 문제의 출현과 단계별 해상도 프로세스를 소개합니다.
1. 문제 발생 :
시나리오 복원 : 인터페이스의 메소드, 먼저 순서 상태를 수정 한 다음 메시지 큐에서 메시지를 생성합니다. 메시지 큐의 소비자는 메시지 감지 순서 상태를 얻고 주문 상태가 변경되지 않았 음을 발견합니다.
암호:
@Service (OrderApi) 공개 클래스 OrderApiimpl은 ORDERAPI {@RESOURCE MQSERVICE MQSERVICE를 구현합니다. @Orderdao Orderdao; public void push (String OrderId) {// 순서 상태를 업데이트하면 이전 상태는 1 updatestatus (OrderId, 3)입니다. // 메시지를 생성합니다. } public viod updatestatus (String OrderId, 정수 상태) {OrderDao.upDatestatus (OrderId, status); }}문제의 이유 : OrderApi의 모든 방법에는 트랜잭션이 있고 트랜잭션 유형 propagation_required가 있으므로 모든 푸시 코드가 실행 된 후 데이터에서 푸시 메소드의 작동이 제출됩니다. 트랜잭션이 제출되기 전에 메시지 대기열 메시지가 생성되었으므로 데이터베이스의 메시지 큐 쿼리에 소비 된 주문 상태는 1 일 수 있습니다. 버그를보다 명확하게하기 위해서는 푸시 메소드의 끝에서 추가 할 수 있습니다.
try {stride.sleep (10000);} catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace ();}이러한 방식으로 소비 메시지가 소비 될 때 주문 상태가 수정되지 않았 음을 알 수 있습니다.
2. 문제에 대한 해결책 :
솔루션 : 데이터를 업데이트 할 때 업데이트 코드가 실행 된 후 데이터베이스를 업데이트하는 트랜잭션이 커밋되었는지 확인하십시오. (메시지가 생성되기 전에 데이터베이스 작업이 제출되었는지 확인하십시오)
위의 체계에 따르면, 내가 생각하는 첫 번째는 Updatestatus 메소드의 트랜잭션 유형을 직접 수정하는 것입니다. 이 방법의 트랜잭션 유형을 propagation_requires_new로 변경했습니다 (트랜잭션이 현재 존재하는 경우 현재 트랜잭션이 중단됨).
그러나 두 가지 부적절한 일이 있습니다.
1. Updatestaus 거래 유형의 강제 수정은 다른 프로세스에 영향을 줄 수 있습니다.
2. 작동하지 않으면 Updatestaus 방법에서는 새로운 거래가 생성되지 않았습니다.
두 번째 포인트에 대한 설명 : Spring은 Beannameautoproxycreator를 통해 트랜잭션을 추가하여 Bean 객체에만 거래를 추가합니다. 이제 수업 내에서 메소드를 호출해도 새로운 것들이 생성되지 않습니다.
위의 시도를 한 후 새로운 수업을 만들었습니다.
@Service ( "OrderextApi") 공개 클래스 OrderextApiimpl {@Resource OrderApi OrdePI; public void updatestatusNewPropagation (String OrderId) {OrdePi.updatestatus (OrderId); }}updatestatusNewPropagation 메소드를 위해 트랜잭션 propagation_requires_new를 추가하십시오
이 클래스는 OrderApi의 Updatestaus 메소드에 대한 새로운 트랜잭션을 작성하는 것입니다.
좋아, 지금까지 버그가 해결되었습니다.
그러나 코드에는 여전히 문제가 있습니다. 데이터베이스의 작동이 제출되었으며 제작 메시지에 예외가있는 경우 비즈니스 로직에 여전히 잘못된 것입니다. 따라서 메시지 생성이 완료되는지 여부를 감지해야합니다.
최종 OrderApi의 코드는 다음과 같습니다.
@Service (OrderApi) 공개 클래스 OrderApiimpl은 ORDERAPI {@RESOURCE MQSERVICE MQSERVICE를 구현합니다. @Resource Orderdao Orderdao; @Resource OrderextApiimpl OrderextApi; public void push (String OrderId) {// 순서 상태를 업데이트하십시오. 이전 상태는 1 OrderextApi.upDatestatusNewPropAgation (OrderId, 3)입니다. // 메시지 생성 -프로모션은 예외가 발생하는지 여부를 감지합니다. 1이 반환되면 생산 메시지가 성공했음을 의미합니다. 응답 응답 = mqservice.prector (OrderId); if (response.getCode ()! = 1) {log.info ( "메시지 대기열 제작 메시지 예외 :" + response.getErrormsg ()) // 생산 메시지 예외, 상태를 재설정하고 다음 재진체 OrderExtApi.upDatesTatusNewPropagation (OrderId, 1); }} public viod updatestatus (String OrderId, 정수 상태) {OrderDao.upDatestatus (OrderId, status); }}위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.