seata(5):dubbo

2023-09-22 13:03:10 浏览数 (2)

接着看下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);
    }

0 人点赞