接着看下dubbo模式的源码,它的实现和api其实很相似,只不过从单体服务变成了4个微服务,首先看下三个RM的实现,基本没有变化,比如Account
代码语言:javascript复制 public void debit(String userId, int money) {
LOGGER.info("Account Service ... xid: " RootContext.getXID());
LOGGER.info("Deducting balance SQL: update account_tbl set money = money - {} where user_id = {}", money,
userId);
jdbcTemplate.update("update account_tbl set money = money - ? where user_id = ?", new Object[] {money, userId});
LOGGER.info("Account Service End ... ");
}
order和stock也类似就不介绍了。TM抽象出了一个BusinessServiceImpl,它实现的区别是什么呢?去掉了申请全局事务id,然后通过try cache判断是否出错来决定提交事务还是回滚事务,多了一个 @GlobalTransactional注解
代码语言:javascript复制@Override
@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")
public void purchase(String userId, String commodityCode, int orderCount) {
LOGGER.info("purchase begin ... xid: " RootContext.getXID());
stockService.deduct(commodityCode, orderCount);
// just test batch update
//stockService.batchDeduct(commodityCode, orderCount);
orderService.create(userId, commodityCode, orderCount);
if (random.nextBoolean()) {
throw new RuntimeException("random exception mock!");
}
}
相应的,我们到,src/main/resources/spring/dubbo-business.xml里面可以看到,它除了使用dubbo协议暴露服务外
代码语言:javascript复制 <dubbo:application name="dubbo-demo-app">
<dubbo:parameter key="qos.enable" value="false"/>
<dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
<dubbo:parameter key="qos.port" value="33333"/>
</dubbo:application>
<dubbo:registry address="multicast://224.5.6.7:1234?unicast=false"/>
还加入了一个bean,通过这个bean完成注解的扫描,通过注解实现动态代理,添加事务执行和回滚对应的切片代码,降低了代码的复杂性。
代码语言:javascript复制 <bean class="io.seata.spring.annotation.GlobalTransactionScanner">
<constructor-arg value="dubbo-demo-app"/>
<constructor-arg value="my_test_tx_group"/>
</bean>
除了上述代码外,还实现了几个对应的starter,开启一个新的线程,等待退出之前来清理资源
代码语言:javascript复制 public static void main(String[] args) {
/**
* 3. Order service is ready . Waiting for buyers to order
*/
ClassPathXmlApplicationContext orderContext = new ClassPathXmlApplicationContext(
new String[] {"spring/dubbo-order-service.xml"});
orderContext.getBean("service");
new ApplicationKeeper(orderContext).keep();
}
在keeper里面注册了shutDown的hook方法
代码语言:javascript复制 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
然后在我们的testClient里面触发执行我们的业务。
代码语言:javascript复制 public static void main(String[] args) {
/**
* 4. The whole e-commerce platform is ready , The buyer(U100001) create an order on the sku(C00321) , the
* count is 2
*/
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"spring/dubbo-business.xml"});
final BusinessService business = (BusinessService)context.getBean("business");
business.purchase("U100001", "C00321", 200);
}