请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

tcc-transaction

老师,我在使用tcc-transaction时,只能调用到服务消费者端的confirm或cancel方法,并不能调用到服务提供者端的confirm或cancel方法。下面是我的代码,请您帮忙看下问题出在哪里?

第一种情况

服务接口com.example.api.transaction.TransactionServiceAPI

public interface TransactionServiceAPI {

    @Compensable
    void sendMessage(String message);

}

服务提供者com.example.provider.service.impl.transaction.TransactionServiceImpl

@Component
@Service(interfaceClass = TransactionServiceAPI.class)
public class TransactionServiceImpl implements TransactionServiceAPI {
    @Override
    @Compensable(confirmMethod = "confirmSendMessage", cancelMethod = "cancelSendMessage", transactionContextEditor = DubboTransactionContextEditor.class)
    public void sendMessage(String message) {
        System.out.println("provider try");
        if (message.equals("123")) {
            throw new NullPointerException();
        }
    }


    public void confirmSendMessage(String message) {
        System.out.println("provider confirm");
    }

    public void cancelSendMessage(String message) {
        System.out.println("provider cancel");
    }

}

服务消费者com.example.consumer.transaction.TransactionConsumer

@Component
public class TransactionConsumer {

    @Autowired
    TransactionServiceAPI transactionServiceAPI;

    @Compensable(confirmMethod = "confirmSendMessage", cancelMethod = "cancelSendMessage", transactionContextEditor = DubboTransactionContextEditor.class)
    public void sendMessage(String message) {
        System.out.println("consumer try");
        transactionServiceAPI.sendMessage(message);
    }


    public void confirmSendMessage(String message) {
        System.out.println("consumer confirm");
    }

    public void cancelSendMessage(String message) {
        System.out.println("consumer cancel");
    }
}

服务消费者端的tcc-transaction-dubbo.xml

 <dubbo:registry protocol="zookeeper" address="182.61.22.173:2181"/>
    <dubbo:application name="transaction-consumer" />
    <dubbo:reference id="transactionServiceAPI" timeout="50000" interface="com.example.api.transaction.TransactionServiceAPI" />

服务消费者端启动类com.example.consumer.ConsumerApplication

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(ConsumerApplication.class, args);
        TransactionConsumer transactionConsumer = (TransactionConsumer)run.getBean("transactionConsumer");
        transactionConsumer.sendMessage("123");
    }

}

运行结果:
服务消费者端输出如下:

consumer try
consumer cancel
Exception in thread "main" java.lang.NullPointerException

服务提供者端输出如下:

provider try

我的问题:照理说,服务提供者端不是应该输出以下内容吗?

provider try
provider cancel

但是,实际情况并没有输出provider cancel,也就是服务提供者端没有调用到cancel方法。

第二种情况

服务接口TransactionServiceAPI

public interface TransactionServiceAPI {

    /**
     * 背景:传入购票数量、传入购买座位、影厅编号
     * 业务:
     * 1. 判断传入的座位是否存在
     * 2. 查询过往订单,判断座位是否已售
     * 3. 新增订单
     * 逻辑:
     * 1. 新增一条订单
     * 2. 判断作为是否存在 & 是否已售
     * 3. 任意一条为假,则修改订单为无效状态
     */

    //判断是否为真座位
    @Compensable
    boolean isTrueSeats(String seats);

    //是否已售
    @Compensable
    boolean isNotSold(String seats);

    //保存订单
    @Compensable
    String saveOrder(String fieldId, String seats, String seatsNum);

}

服务提供者TransactionServiceImpl

@Component
@Service(interfaceClass = TransactionServiceAPI.class)
public class TransactionServiceImpl implements TransactionServiceAPI {
    @Override
    @Compensable(confirmMethod = "confirmSendMessage", cancelMethod = "cancelSendMessage", transactionContextEditor = DubboTransactionContextEditor.class)
    public void sendMessage(String message) {
        System.out.println("provider try");
        if (message.equals("123")) {
            throw new NullPointerException();
        }
    }

    @Override
    @Compensable(confirmMethod = "confirmIsTrueSeats", cancelMethod = "cancelIsTrueSeats", transactionContextEditor = DubboTransactionContextEditor.class)
    public boolean isTrueSeats(String seats) {
        System.out.println("provider isTrueSeats");
        if(seats.equals("1,2,3")){
            throw new IllegalArgumentException();
        }
        return true;
    }

    @Override
    @Compensable(confirmMethod = "confirmIsNotSold", cancelMethod = "cancelIsNotSold", transactionContextEditor = DubboTransactionContextEditor.class)
    public boolean isNotSold(String seats) {
        System.out.println("provider isNotSold");
        if(seats.equals("4,5")){
            throw new IllegalArgumentException();
        }
        return true;
    }

    /**
     * 千万注意幂等性的问题
     * @param fieldId
     * @param seats
     * @param seatsNum
     * @return
     */
    @Override
    @Compensable(confirmMethod = "confirmSaveOrder", cancelMethod = "cancelSaveOrder", transactionContextEditor = DubboTransactionContextEditor.class)
    public String saveOrder(String fieldId, String seats, String seatsNum) {
        System.out.println("provider saveOrder");
        return "";
    }

    public String confirmSaveOrder(String fieldId, String seats, String seatsNum) {
        System.out.println("provider confirmSaveOrder");
        return "";
    }

    public String cancelSaveOrder(String fieldId, String seats, String seatsNum) {
        System.out.println("provider cancelSaveOrder");
        return "";
    }


    public boolean confirmIsTrueSeats(String seats) {
        System.out.println("provider confirmIsTrueSeats");
        return true;
    }

    public boolean cancelIsTrueSeats(String seats) {
        System.out.println("provider cancelIsTrueSeats");
        return true;
    }

    public boolean confirmIsNotSold(String seats) {
        System.out.println("provider confirmIsNotSold");
        return true;
    }

    public boolean cancelIsNotSold(String seats) {
        System.out.println("provider cancelIsNotSold");
        return true;
    }

}

服务消费者TransactionServiceAPI

@Component
public class TransactionConsumer {

    @Autowired
    TransactionServiceAPI transactionServiceAPI;

    @Compensable(confirmMethod = "confirmOrder", cancelMethod = "cancelOrder", transactionContextEditor = DubboTransactionContextEditor.class)
    public void order(String message) {
        transactionServiceAPI.saveOrder("001", message, "5");
        transactionServiceAPI.isTrueSeats(message);
        transactionServiceAPI.isNotSold(message);
    }

    public void confirmOrder(String message) {
        System.out.println("consumer confirmOrder");
    }

    public void cancelOrder(String message) {
        System.out.println("consumer cancelOrder");
    }
}

服务消费者端启动类ConsumerApplication

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(ConsumerApplication.class, args);
        TransactionConsumer transactionConsumer = (TransactionConsumer) run.getBean("transactionConsumer");
        transactionConsumer.order("4,5");
    }

}

运行结果:
服务消费者端输出:

consumer cancelOrder
Exception in thread "main" java.lang.IllegalArgumentException

服务提供者端输出:

provider saveOrder
provider isTrueSeats
provider isNotSold
provider cancelIsTrueSeats
provider cancelIsNotSold

我真的懵了,不知道问题出在哪?

正在回答 回答被采纳积分+3

1回答

Allen 2020-02-23 22:26:13

错误内容多截一些图, 这个错误提示不太明确

0 回复 有任何疑惑可以回复我~
  • 提问者 Moss1105 #1
    错误提示都是我的代码里抛出来的,比如
    if(seats.equals("4,5")){
             throw new IllegalArgumentException();
     }
    回复 有任何疑惑可以回复我~ 2020-02-23 22:29:19
  • 提问者 Moss1105 #2
    我先把tcc-transaction给的dubbo示例跑一下,看一下运行结果,想想问题出在哪
    回复 有任何疑惑可以回复我~ 2020-02-23 22:42:28
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信