what I mean is that the bigger surrogateId will update  the variable 
"nextEndedEventId" and alpha cannot find the smaller one.

> eventRepository.findFirstUncompensatedEventByIdGreaterThan(nextEndedEventId, 
> TxEndedEvent.name())
        .forEach(event -> {
          LOG.info("Found uncompensated event {}", event);
          nextEndedEventId = event.id();
          commandRepository.saveCompensationCommands(event.globalTxId());
        });
@Query("SELECT t FROM TxEvent t "
      + "WHERE t.type = ?1 AND t.surrogateId > ?2 AND EXISTS ( "
      + "  SELECT t1.globalTxId FROM TxEvent t1 "
      + "  WHERE t1.globalTxId = t.globalTxId "
      + "    AND t1.type = 'TxAbortedEvent' AND NOT EXISTS ( "
      + "    SELECT t2.globalTxId FROM TxEvent t2 "
      + "    WHERE t2.globalTxId = t1.globalTxId "
      + "      AND t2.localTxId = t1.localTxId "
      + "      AND t2.type = 'TxStartedEvent' "
      + "      AND t2.creationTime > t1.creationTime)) AND NOT EXISTS ( "
      + "  SELECT t3.globalTxId FROM TxEvent t3 "
      + "  WHERE t3.globalTxId = t.globalTxId "
      + "    AND t3.localTxId = t.localTxId "
      + "    AND t3.type = 'TxCompensatedEvent') AND ( "
      + "  SELECT MIN(t4.retries) FROM TxEvent t4 "
      + "  WHERE t4.globalTxId = t.globalTxId "
      + "    AND t4.localTxId = t.localTxId "
      + "    AND t4.type = 'TxStartedEvent' ) = 0 "
      + "ORDER BY t.surrogateId ASC")
  List<TxEvent> findFirstByTypeAndSurrogateIdGreaterThan(String type, long 
surrogateId, Pageable pageable);

Take the saga-spring-demo as example.
There are two request at the same time. They firstly invoke the car service and 
succeed. Then they invoke the hotel service,but the hotel service fail.
if we can't ensure the order of message of two different invocations, Alpha may 
receive messages in the following order:
<img width="673" alt="5c1da0985073e2642b6429432d974011" 
src="https://user-images.githubusercontent.com/9289881/44309435-294e9480-a3f9-11e8-8755-cdfb02d6bd66.png";>

`


    String sagaGlobalId = UUID.randomUUID().toString(); //Request1
    String bookingApplicationLocalId = UUID.randomUUID().toString();
    String carServiceLocalId = UUID.randomUUID().toString();
    String hotelServiceLocalId = UUID.randomUUID().toString();

    String anotherSagaGlobalId = UUID.randomUUID().toString();//Request2
    String anotheBookingApplicationLocalId = UUID.randomUUID().toString();
    String anotherCarServiceLocalId = UUID.randomUUID().toString();
    String anotherHoterServceiLocalId = UUID.randomUUID().toString();

    asyncStub.onConnected(serviceConfig, compensateResponseObserver);

    blockingStub.onTxEvent(someGrpcEvent(SagaStartedEvent, sagaGlobalId, 
bookingApplicationLocalId));
    blockingStub.onTxEvent(someGrpcEvent(SagaEndedEvent, anotherSagaGlobalId, 
anotheBookingApplicationLocalId));

    blockingStub.onTxEvent(someGrpcEvent(TxStartedEvent, sagaGlobalId, 
carServiceLocalId));
    blockingStub.onTxEvent(someGrpcEvent(TxEndedEvent, sagaGlobalId, 
carServiceLocalId));
    //surrogateId --> 4

    blockingStub.onTxEvent(someGrpcEvent(TxStartedEvent, anotherSagaGlobalId, 
anotherCarServiceLocalId));
    blockingStub.onTxEvent(someGrpcEvent(TxEndedEvent, anotherSagaGlobalId, 
anotherCarServiceLocalId));
    //surrogateId --> 6

    blockingStub.onTxEvent(someGrpcEvent(TxStartedEvent, sagaGlobalId, 
hotelServiceLocalId));
    blockingStub.onTxEvent(someGrpcEvent(TxStartedEvent, anotherSagaGlobalId, 
anotherHoterServceiLocalId));

    //the latter hotelservice abort event come first
    blockingStub.onTxEvent(someGrpcEvent(TxAbortedEvent, anotherSagaGlobalId, 
anotherHoterServceiLocalId));
    await().atMost(2, SECONDS).until(() -> !receivedCommands.isEmpty());


    //the TxAbortedEvent of the first hotelservice TxAbortedEvent didn't come 
until the previous TxAbortedEvent has been found
    blockingStub.onTxEvent(someGrpcEvent(TxAbortedEvent, sagaGlobalId, 
hotelServiceLocalId));

    //now, the variable "nextEndedEventId" is 6, so the TxEndedEvent whose 
surrogateId is 4 can't be found.
    await().atMost(10, SECONDS).until(() -> receivedCommands.size() > 1);
    assertThat(receivedCommands.size(), is(2));
`



[ Full content available at: 
https://github.com/apache/incubator-servicecomb-saga/issues/253 ]
This message was relayed via gitbox.apache.org for [email protected]

Reply via email to