Actual combat of xbank project of Biz SIP Middleware -- assembly of delay service in application layer

Keywords: Microservices Container Cloud Native

xbank project version Library: https://gitee.com/szhengye/xbank.git

Project practice: assembly of application services to deferred services

1. Implementation of SAF store and forward

In the domain layer, Payment2SinkService is developed to handle various exceptions such as timeout, failure and success according to the tranMode transaction mode:

@Service
public class Payment2SinkService implements JSONObjectSinkBeanInterface {
    @Autowired
    private TimeoutCmdExe timeoutCmdExe;
    @Autowired
    private TimeoutAndFailCmdExe timeoutAndFailCmdExe;
    @Autowired
    private TimeoutAndSuccessCmdExe timeoutAndSuccessCmdExe;
    @Autowired
    private SuccessCmdExe successCmdExe;

    @Override
    public JSONObject process(JSONObject jsonObject) throws BizException {
        log.info("incoming message :\n{}", jsonObject.toString());
        AbstractSinkBeanCmdExe sinkBeanCmdExe;
        String tranMode = (String)jsonObject.get("tranMode");
        switch (tranMode) {
            case "timeout":
                // After receiving the transaction, the timeout is always returned
                return timeoutCmdExe.execute(jsonObject);
            case "3timeout-fail":
                // After receiving the transaction, the first 3 times of return timeout and the fourth time of return failure code
                return timeoutAndFailCmdExe.execute(jsonObject);
            case "3timeout-success":
                // After receiving the transaction, the first three returns timeout, and the fourth successfully returns the original message
                return timeoutAndSuccessCmdExe.execute(jsonObject);
            default:
                //In other cases, the original message is returned successfully
                return successCmdExe.execute(jsonObject);
        }
    }
}

Note that the encapsulation of the Payment2 domain service involves multiple interface calls. The Command Executor is used for each interface. Here, the standard JSONObject data is passed in, so all interface implementations inherit the AbstractSinkBeanCmdExe class:

In the application layer, send2Payment2() and getCustomerAndSaf2Payment2() method interfaces and implementations are added to the original personalapppinterface application layer interface and PersonalAppService service class. Multiple SAF calls to the original send2Payment2() method are realized through the personalAppDelayInterface delay call interface:

@Service
public class PersonalAppService implements PersonalAppInterface {
    ...
        
    private BizMessageInterface payment2SinkInterface = IntegratorClientFactory
            .getSinkClient(BizMessageInterface.class,"payment2-sink");
    private PersonalAppInterface personalAppDelayInterface = IntegratorClientFactory
            .getDelayBizServiceClient(PersonalAppInterface.class,"app/personal",
                    0,1000,2000,4000,8000,16000,32000);
	...
        
    @Override
    public BizMessage send2Payment2(String tranMode, String tranCode, Object message) throws BizException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("tranCode",tranCode);
        jsonObject.set("tranMode",tranMode);
        jsonObject.set("message",message);
        return this.payment2SinkInterface.call(jsonObject);
    }

    @Override
    public Customer getCustomerAndSaf2Payment2(String tranMode,String customerId) throws BizException {
        Customer customer = this.customerSinkInterface.getCustomer(customerId);
        this.personalAppDelayInterface.send2Payment2(tranMode,"send-customer", customer);
        return customer;
    }
    ...
}

The incoming transaction mode is "timeout" (always return timeout after receiving the transaction), which will lead to 7 times of sending, and the final transaction status is failed:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"getCustomerAndSaf2Payment2","params":["timeout","001"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "c1d2ffb7f0b44bf4b0cb7e13e5c0c0fa",
  "parentTraceId": null,
  "timestamp": 1631274896174,
  "data": {
    "result": {
      "sex": "1",
      "customerName": "Zhang San",
      "customerId": "001",
      "age": 30
    }
  }
}

Payment2SinkApplication log:

2021-09-10 19:54:56.650  INFO 14993 --- [nio-8004-exec-3] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:54:56.651  INFO 14993 --- [nio-8004-exec-3] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:54:57.753  INFO 14993 --- [nio-8004-exec-4] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:54:57.754  INFO 14993 --- [nio-8004-exec-4] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:54:59.920  INFO 14993 --- [nio-8004-exec-5] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:54:59.920  INFO 14993 --- [nio-8004-exec-5] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:55:04.015  INFO 14993 --- [nio-8004-exec-6] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:55:04.015  INFO 14993 --- [nio-8004-exec-6] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:55:12.041  INFO 14993 --- [nio-8004-exec-7] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:55:12.042  INFO 14993 --- [nio-8004-exec-7] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:55:28.080  INFO 14993 --- [nio-8004-exec-8] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:55:28.080  INFO 14993 --- [nio-8004-exec-8] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:56:00.228  INFO 14993 --- [nio-8004-exec-9] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"timeout","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:56:00.228  INFO 14993 --- [nio-8004-exec-9] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!

The incoming transaction code is "3timeout fail" (after receiving the transaction, the first three times return timeout, and the fourth time return failure), which will lead to four times of sending, and the final transaction status is failure:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"getCustomerAndSaf2Payment2","params":["3timeout-fail","001"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "d3589b169d654a409c2f7d15f83f5113",
  "parentTraceId": null,
  "timestamp": 1631275051123,
  "data": {
    "result": {
      "sex": "1",
      "customerName": "Zhang San",
      "customerId": "001",
      "age": 30
    }
  }
}

Payment2SinkApplication log:

2021-09-10 19:57:31.379  INFO 14993 --- [nio-8004-exec-1] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-fail","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:57:31.379  INFO 14993 --- [nio-8004-exec-1] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:57:32.647  INFO 14993 --- [nio-8004-exec-2] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-fail","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:57:32.647  INFO 14993 --- [nio-8004-exec-2] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:57:34.672  INFO 14993 --- [nio-8004-exec-3] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-fail","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:57:34.673  INFO 14993 --- [nio-8004-exec-3] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:57:38.733  INFO 14993 --- [nio-8004-exec-4] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-fail","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:57:38.733  INFO 14993 --- [nio-8004-exec-4] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Failed to return transaction processing!

The incoming transaction code is "3timeout success" (after receiving the transaction, the first three times return timeout, and the fourth time successfully return the original message), which will lead to four times of sending, and the final transaction status is success:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"getCustomerAndSaf2Payment2","params":["3timeout-success","001"]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "75b76cf518164964bedf477ea488698c",
  "parentTraceId": null,
  "timestamp": 1631275117934,
  "data": {
    "result": {
      "sex": "1",
      "customerName": "Zhang San",
      "customerId": "001",
      "age": 30
    }
  }
}

Payment2SinkApplication log:

2021-09-10 19:58:38.146  INFO 14993 --- [nio-8004-exec-5] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-success","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:58:38.146  INFO 14993 --- [nio-8004-exec-5] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:58:39.200  INFO 14993 --- [nio-8004-exec-6] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-success","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:58:39.200  INFO 14993 --- [nio-8004-exec-6] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:58:41.409  INFO 14993 --- [nio-8004-exec-7] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-success","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:58:41.409  INFO 14993 --- [nio-8004-exec-7] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return timeout exception!
2021-09-10 19:58:45.539  INFO 14993 --- [nio-8004-exec-8] c.x.d.p.service.Payment2DomainService    : incoming message :
{"tranMode":"3timeout-success","message":{"sex":"1","customerName":"Zhang San","customerId":"001","age":30},"tranCode":"send-customer"}
2021-09-10 19:58:45.539  INFO 14993 --- [nio-8004-exec-8] c.x.d.p.service.Payment2DomainService    : transaction:send-customer,Return transaction success!

2. Realization of forward compensation

The forward compensation mechanism means that when there is no response to the transaction, the system will query the original transaction. If the query times out, it will be retried multiple times. If the original transaction succeeds, the subsequent transaction will continue. If the original transaction fails, the transaction compensation will be made to the previous transaction. Forward compensation is generally a solution for the third-party recipient who cannot provide compensation transactions.
In the financial field, this kind of transaction compensation action is often called "reversal".
In the application layer, payoutForward() and payoutForwardCompensate() method interfaces and implementations are added to the original personalapppinterface application layer interface and PersonalAppService service class. Multiple repeated delayed calls to the original payoutForwardCompensate() method are realized through the personalAppDelayInterface delayed call interface:

@Service
public class PersonalAppService implements PersonalAppInterface {
    private AccountSinkInterface accountSinkInterface = IntegratorClientFactory
            .getSinkClient(AccountSinkInterface.class,"account-sink");
    private CustomerSinkInterface customerSinkInterface = IntegratorClientFactory
            .getSinkClient(CustomerSinkInterface.class,"customer-sink");
    private BizMessageInterface payment1SinkInterface = IntegratorClientFactory
            .getSinkClient(BizMessageInterface.class,"payment1-sink");
    private BizMessageInterface payment2SinkInterface = IntegratorClientFactory
            .getSinkClient(BizMessageInterface.class,"payment2-sink");
    private PersonalAppInterface personalAppDelayInterface = IntegratorClientFactory
            .getDelayBizServiceClient(PersonalAppInterface.class,"app/personal",
                    0,1000,2000,4000,8000,16000,32000);
    
    ......
        
	@Override
    public void payoutForward(String tranMode,String accountId, long amount) throws BizException {
        log.info("account Out of gold:{},{}",accountId,amount);
        this.accountDomainInterface.payout(accountId,amount);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("tranCode","pay");
        jsonObject.set("tranMode",tranMode);
        jsonObject.set("accountId",accountId);
        jsonObject.set("tranAmount",amount);
        BizMessage<JSONObject> bizMessage = null;
        try {
            log.info("payment pay...");
            bizMessage = this.payment2SinkInterface.call(jsonObject);
        } catch (BizException e) {
            if (e.isTimeOutException()) {
                log.info("payment Transaction timeout,start payout compensate...");
                this.personalAppDelayInterface.payoutForwardCompensate(jsonObject);
                return;
            }
            else {
                throw e;
            }
        }
        log.info("payment Payment succeeded!");
        log.info("payout success!");
    }

    @Override
    public void payoutForwardCompensate(JSONObject jsonObject)  throws BizException{
        jsonObject.set("tranCode","pay-query");
        BizMessage<JSONObject> bizMessage = null;
        try {
            log.info("payment Query payment order...");
            bizMessage = this.payment2SinkInterface.call(jsonObject);
        } catch (BizException e) {
            if (e.isTimeOutException()) {
                log.info("payment Transaction timeout...");
                throw e;
            }
            else {
                log.info("payment Error returned from querying payment order (indicating that the opposite order has not been executed)...");
                String accountId = (String)jsonObject.get("accountId");
                long amount = (Integer) jsonObject.get("tranAmount");
                log.info("account Payment compensation:{},{}",accountId,amount);
                this.accountDomainInterface.payoutCompensation(accountId,amount);
                return;
            }
        }
        log.info("payment Successful query of payment order (indicating that the opposite order has been executed)");
        log.info("payout success!");
    }

The incoming transaction mode is "3timeout success" (after receiving the order transaction, the first three times will return timeout, and the fourth time will return simulation that the order has been executed). This will lead to four times of sending, and the final transaction status is success:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"payoutForward","params":["3timeout-success","0001",1]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "e0127a25e2514da682ad77042917087a",
  "parentTraceId": null,
  "timestamp": 1631275840559,
  "data": {}
}

XbankAppApplication log:

[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:40.560 INFO 16503 [11034350FE38437BB459F1E8DC6CCE17] [http-nio-8888-exec-5] c.xbank.app.service.PersonalAppService   account Out of gold:0001,1
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:40.822 INFO 16503 [11034350FE38437BB459F1E8DC6CCE17] [http-nio-8888-exec-5] c.xbank.app.service.PersonalAppService   payment pay...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:40.831 INFO 16503 [11034350FE38437BB459F1E8DC6CCE17] [http-nio-8888-exec-5] c.xbank.app.service.PersonalAppService   payment Transaction timeout,start payout compensate...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:42.086 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:42.095 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:43.268 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:43.277 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice payment transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:45.296 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:45.306 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2] c.xbank.app.service.personalappservice payment query succeeded (indicating that the opposite order has been executed)
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:10:45.306 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2] c.xbank.app.service.personalappservice payout succeeded!

The incoming transaction mode is "3timeout success" (after receiving the order transaction, the first three times will return timeout, and the fourth time will return simulation that the order has been executed). This will lead to four times of sending, and the final transaction status is success:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"payoutForward","params":["3timeout-fail","0001",1]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "a04163bf05484fa28071650a085d4124",
  "parentTraceId": null,
  "timestamp": 1631275997342,
  "data": {}
}

XbankAppApplication log:

[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:17.342 INFO 16503 [5E5951618A27430684C5552E1F782D8B] [http-nio-8888-exec-7] c.xbank.app.service.PersonalAppService   account Out of gold:0001,1
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:17.568 INFO 16503 [5E5951618A27430684C5552E1F782D8B] [http-nio-8888-exec-7] c.xbank.app.service.PersonalAppService   payment pay...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:17.579 INFO 16503 [5E5951618A27430684C5552E1F782D8B] [http-nio-8888-exec-7] c.xbank.app.service.PersonalAppService   payment Transaction timeout,start payout compensate...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:17.775 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-5] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:17.788 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-5] c.xbank.app.service.personalappservice payment transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:18.827 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:18.836 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:20.890 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment query payment order
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:20.900 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment query returned an error (indicating that the opposite order was not executed)
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:13:20.901 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice account: 0001,1

3. Realization of backward compensation

The backward compensation mechanism means that when there is no response to the transaction, the system will initiate multiple transaction compensation retries for the original transaction. If the compensation transaction is successful, the previous transaction will be compensated.
In the application layer, payoutBackward() and payoutBackwardCompensate() method interfaces and implementations are added to the original personalapppinterface application layer interface and PersonalAppService service class. Multiple repeated delayed calls to the original payoutForwardCompensate() method are realized through the personalAppDelayInterface delayed call interface:

@Service
public class PersonalAppService implements PersonalAppInterface {
    private AccountSinkInterface accountSinkInterface = IntegratorClientFactory
            .getSinkClient(AccountSinkInterface.class,"account-sink");
    private CustomerSinkInterface customerSinkInterface = IntegratorClientFactory
            .getSinkClient(CustomerSinkInterface.class,"customer-sink");
    private BizMessageInterface payment1SinkInterface = IntegratorClientFactory
            .getSinkClient(BizMessageInterface.class,"payment1-sink");
    private BizMessageInterface payment2SinkInterface = IntegratorClientFactory
            .getSinkClient(BizMessageInterface.class,"payment2-sink");
    private PersonalAppInterface personalAppDelayInterface = IntegratorClientFactory
            .getDelayBizServiceClient(PersonalAppInterface.class,"app/personal",
                    0,1000,2000,4000,8000,16000,32000);
    
    ......
        
	@Override
    public void payoutBackward(String tranMode, String accountId, long amount) throws BizException {
        log.info("account Out of gold:{},{}",accountId,amount);
        this.accountDomainInterface.payout(accountId,amount);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("tranCode","pay");
        jsonObject.set("tranMode",tranMode);
        jsonObject.set("accountId",accountId);
        jsonObject.set("tranAmount",amount);
        BizMessage<JSONObject> bizMessage = null;
        try {
            log.info("payment pay...");
            bizMessage = this.payment2SinkInterface.call(jsonObject);
        } catch (BizException e) {
            if (e.isTimeOutException()) {
                log.info("payment Transaction timeout,start payout Righting...");
                this.personalAppDelayInterface.payoutBackwardCompensate(jsonObject);
                return;
            }
            else {
                log.info("payment Payment transaction return error");
                log.info("account Payment compensation:{},{}",accountId,amount);
                this.accountDomainInterface.payoutCompensation(accountId,amount);
                log.info("payout Transaction compensation succeeded!");
                return;
            }
        }
        log.info("payment Payment succeeded");
        log.info("payout success!");
    }

    @Override
    public void payoutBackwardCompensate(JSONObject jsonObject) throws BizException {
        jsonObject.set("tranCode","pay-reversal");
        BizMessage<JSONObject> bizMessage;
        try {
            log.info("payment Payment compensation...");
            bizMessage = this.payment2SinkInterface.call(jsonObject);
            log.info("payment Payment compensation succeeded");
        } catch (BizException e) {
            if (e.isTimeOutException()) {
                log.info("payment Payment compensation transaction timeout...");
                throw e;
            }
            log.info("payment Payment compensation transaction failed,Manual intervention adjustment is required!");
            return;
        }
        String accountId = (String)jsonObject.get("accountId");
        long amount = (Integer)jsonObject.get("tranAmount");
        log.info("account Payment compensation:{},{}",accountId,amount);
        this.accountDomainInterface.payoutCompensation(accountId,amount);
        log.info("payout Compensation succeeded!");
    }

The incoming transaction mode is "3timeout success" (after receiving the order transaction, the compensation transaction timeout is returned for the first three times, and the compensation transaction execution success is returned for the fourth time). This will lead to four times of sending, and the final transaction status is success:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"payoutBackward","params":["3timeout-success","0001",1]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "26c58fe44b3f4ceba462762494fa5981",
  "parentTraceId": null,
  "timestamp": 1631276405513,
  "data": {}
}

XbankAppApplication log:

[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:05.513 INFO 16503 [84936F44451449C5A92183EF93C3690C] [http-nio-8888-exec-2] c.xbank.app.service.PersonalAppService   account Out of gold:0001,1
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:05.952 INFO 16503 [84936F44451449C5A92183EF93C3690C] [http-nio-8888-exec-2] c.xbank.app.service.PersonalAppService   payment pay...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:05.961 INFO 16503 [84936F44451449C5A92183EF93C3690C] [http-nio-8888-exec-2] c.xbank.app.service.PersonalAppService   payment Transaction timeout,start payout Righting...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:06.396 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:06.405 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment payment compensation transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:07.468 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:07.475 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-4] c.xbank.app.service.personalappservice payment payment compensation transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:09.560 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:09.570 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice payment compensation succeeded
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:09.571 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice account: 0001,1
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:20:09.726 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-3] c.xbank.app.service.personalappservice payout compensation succeeded!

The incoming transaction mode is "3timeout fail" (after receiving the order transaction, timeout is returned for the first three times, and simulated compensation transaction failure is returned for the fourth time). This will lead to sending 4 times, and the final transaction status is failure:

$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:app/personal" -X POST --data '{"methodName":"payoutBackward","params":["3timeout-fail","0001",1]}' http://localhost:8888/api|jq

{
  "code": 0,
  "message": "success",
  "extMessage": null,
  "traceId": "40aed8f06bba436ba67ff93e769d5a33",
  "parentTraceId": null,
  "timestamp": 1631276555599,
  "data": {}
}

XbankAppApplication log:

[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:35.599 INFO 16503 [B54A535614A64492A7A00D987F12B529] [http-nio-8888-exec-4] c.xbank.app.service.PersonalAppService   account Out of gold:0001,1
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:35.760 INFO 16503 [B54A535614A64492A7A00D987F12B529] [http-nio-8888-exec-4] c.xbank.app.service.PersonalAppService   payment pay...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:35.767 INFO 16503 [B54A535614A64492A7A00D987F12B529] [http-nio-8888-exec-4] c.xbank.app.service.PersonalAppService   payment Transaction timeout,start payout Righting...
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:35.979 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:35.993 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2] c.xbank.app.service.personalappservice payment payment compensation transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:37.073 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-5] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:37.083 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-5] c.xbank.app.service.personalappservice payment payment compensation transaction timeout
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:39.111 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment compensation
[bizsip-integrator:192.169.1.101:8888] 2021-09-10 20:22:39.121 INFO 16503 [] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] c.xbank.app.service.personalappservice payment payment compensation transaction failed. Manual intervention and adjustment are required!

Biz SIP official website: http://bizsip.bizmda.com
Gitee: https://gitee.com/szhengye/biz-sip

Posted by Jak-S on Sun, 10 Oct 2021 00:52:58 -0700