servicecomb-pack icon indicating copy to clipboard operation
servicecomb-pack copied to clipboard

globalTxId is null.

Open twistycs opened this issue 4 years ago • 12 comments

This is Microservice and spring boot All. Service A call Post Method to Service B , C , D by Async Task.

Put @SagaStart Above @PostMapping On controller Service A

Service B Put @Compensable on method that Controller B call this method

Stop service C for Service B to call Compensable to cancel. It calls cancel but globalTx Id is null.

I put this dependency to Service A and B

            <dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-spring-starter</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-transport-resttemplate</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-transport-feign</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-context</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-transaction</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-spring-tx</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-transport-dubbo</artifactId>
		<version>0.5.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.servicecomb.pack</groupId>
		<artifactId>omega-transport-servicecomb</artifactId>
		<version>0.5.0</version>
	</dependency>
==========================================================
java.lang.NullPointerException: null
        at org.apache.servicecomb.pack.contract.grpc.GrpcTxEvent$Builder.setGlobalTxId(GrpcTxEvent.java:999) ~[pack-contract-grpc-0.5.0.jar:0.5.0]
        at org.apache.servicecomb.pack.omega.connector.grpc.saga.GrpcSagaClientMessageSender.convertEvent(GrpcSagaClientMessageSender.java:101) ~[omega-connector-grpc-0.5.0.jar:0.5.0]
        at org.apache.servicecomb.pack.omega.connector.grpc.saga.GrpcSagaClientMessageSender.send(GrpcSagaClientMessageSender.java:90)
~[omega-connector-grpc-0.5.0.jar:0.5.0]
        at org.apache.servicecomb.pack.omega.connector.grpc.saga.SagaLoadBalanceSender$1.apply(SagaLoadBalanceSender.java:45) ~[omega-connector-grpc-0.5.0.jar:0.5.0]
        at org.apache.servicecomb.pack.omega.connector.grpc.saga.SagaLoadBalanceSender$1.apply(SagaLoadBalanceSender.java:42) ~[omega-connector-grpc-0.5.0.jar:0.5.0]
        at org.apache.servicecomb.pack.omega.connector.grpc.core.LoadBalanceSenderAdapter.doGrpcSend(LoadBalanceSenderAdapter.java:54)
~[omega-connector-grpc-0.5.0.jar:0.5.0]
=========================================================

twistycs avatar Apr 10 '20 05:04 twistycs

How do you invoke the Async service? If the GlobalTxId is passed the next service call , you will get the NPE error.

WillemJiang avatar Apr 10 '20 09:04 WillemJiang

Service A Async call B C D and then wait for response B,C,D and then end process .

It's not support with async task?

twistycs avatar Apr 10 '20 09:04 twistycs

Could you show the code which you use @SagaStart and @Componsible?

WillemJiang avatar Apr 10 '20 15:04 WillemJiang

This is Service A Call B, C and D:

    @SagaStart
    @PostMapping("/contract")
    public ResponseEntity<?> serviceA() {
        try {
            CompletableFuture<Response> insertServiceB= serviceB.insertServiceB();
            CompletableFuture<Response> insertServiceC= serviceC.insertServiceC();
            CompletableFuture<Response> insertServiceD= serviceD.insertServiceD();
            CompletableFuture.allOf(insertServiceB,insertServiceC,insertServiceD).join();
           
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Can not created .");
        }
        return ResponseEntity.status(HttpStatus.CREATED)
    }

============================================================ Service B :

@PostMapping()
    public ResponseEntity<?> insertServiceB() {
        try {
            response = serviceB.insertServiceB(customer);
        } catch (final Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Can not insert.");
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

Method Service B :

@Compensable(compensationMethod = "cancel")
    public Response insertServiceB(Customer customer) {
        Response resp = new Response();
        try {
                insertServiceBRepository.save(customer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resp;
    }

 void cancel(Customer customer){
        System.out.println("CANCEL CUSTOMER !!!!!!!!!!!!!!!!!!!!!");
    }

=======================================================

And Stop Service C

twistycs avatar Apr 13 '20 02:04 twistycs

CompletableFuture<Response> insertServiceB= serviceB.insertServiceB(); CompletableFuture<Response> insertServiceC= serviceC.insertServiceC(); CompletableFuture<Response> insertServiceD= serviceD.insertServiceD(); CompletableFuture.allOf(insertServiceB,insertServiceC,insertServiceD).join();

You are using the async invocations here and the calling thread is quite different for each invocation. As Pack uses thread local to store the GID, it makes sense that GID is null, if the calling thread is changed. Can you try to call the service one by one?

WillemJiang avatar Apr 13 '20 07:04 WillemJiang

yes i try to service A call only Service B with sync task not async but globalTxId is null too.

twistycs avatar Apr 13 '20 08:04 twistycs

How did you inject the Omega to ServiceA? GID could be null, if the Omega is not started in a right way. As I cannot check your code here, could you go through the demo code here?

WillemJiang avatar Apr 13 '20 08:04 WillemJiang

@EnableOmega ??

i put this but the type EnableOmega is deprecated.

twistycs avatar Apr 13 '20 08:04 twistycs

It should be fine. Please compare your code with the demo code that I showed to you.

WillemJiang avatar Apr 13 '20 12:04 WillemJiang

In demo what is version of omega-spring-starter ?

i use omega-spring-starter-0.5.0 but anotation @EnableOmega can not use, its deprecated.

I'm not sure if @EnableOmega cant use then GID be null.

twistycs avatar Apr 14 '20 04:04 twistycs

In demo what is version of omega-spring-starter ?

i use omega-spring-starter-0.5.0 but anotation @EnableOmega can not use, its deprecated.

I'm not sure if @EnableOmega cant use then GID be null.

@EnableOmega is deprecated and is enabled by default, I think it has nothing to do with GID null.

We have implemented various request interceptors [1] to implicitly pass GlD and other parameters, I think the interceptor does not work for some reason. Are you using feign to call serviceB?

[1]https://github.com/apache/servicecomb-pack/tree/master/omega/omega-transport

coolbeevip avatar Apr 15 '20 01:04 coolbeevip

Change the log level of Service A to DEBUG, you can see the detailed information of interceptors

coolbeevip avatar Apr 15 '20 03:04 coolbeevip