老师,我在使用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
我真的懵了,不知道问题出在哪?