阿里开源GTS---FESCAR分布式事务

github:https://github.com/alibaba/fescar

1.

把项目下载到本地,启动项目中的examples要适当配置:

1.其中三个xml需要配置数据库的链接地址,以及2个sql文件执行产生4张表

账户表,订单表,库存表,日志表

2.进行测试时首先启动:server项目Server类的main方法,AccountServiceImpl、OrderServiceImpl、StorageServiceImpl实现类的main方法,都是注册到dubbo中作为各个服务,AccountServiceImpl,StorageServiceImpl启动初始化代码会插入一条初始数据:

3.环境准备好后启动BusinessServiceImpl的main方法

 3.1程序会抛出RuntimeException,观察表发现没有数据变化

3.2把异常注释掉,发现库存,账户对应减少,并产生一条订单数据

扫描二维码关注公众号,回复: 10986255 查看本文章

3.3在46行,47行间加入System.out.println(1 / 0);使其产生异常,发现数据没有变化

3.4去掉@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")注解,发现产生脏数据

4.继续查看@GlobalTransactional的实现,在GlobalTransactionalInterceptor类中的invoke方法:

@Override
public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
    final GlobalTransactional anno = getAnnotation(methodInvocation.getMethod());
    if (anno != null) {
        try {
            return transactionalTemplate.execute(new TransactionalExecutor() {
                @Override
                public Object execute() throws Throwable {
                    return methodInvocation.proceed();
                }

                @Override
                public int timeout() {
                    return anno.timeoutMills();
                }

                @Override
                public String name() {
                    String name = anno.name();
                    if (!StringUtils.isEmpty(name)) {
                        return name;
                    }
                    return formatMethod(methodInvocation.getMethod());
                }
            });
        } catch (TransactionalExecutor.ExecutionException e) {
            TransactionalExecutor.Code code = e.getCode();
            switch (code) {
                case RollbackDone:
                    throw e.getOriginalException();
                case BeginFailure:
                    failureHandler.onBeginFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                case CommitFailure:
                    failureHandler.onCommitFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                case RollbackFailure:
                    failureHandler.onRollbackFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                default:
                    throw new ShouldNeverHappenException("Unknown TransactionalExecutor.Code: " + code);

            }
        }

    }
    return methodInvocation.proceed();
}
发现TransactionalTemplate调用了execute方法
public Object execute(TransactionalExecutor business) throws TransactionalExecutor.ExecutionException {

    // 1. get or create a transaction
    GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();

    // 2. begin transaction
    try {
        tx.begin(business.timeout(), business.name());

    } catch (TransactionException txe) {
        throw new TransactionalExecutor.ExecutionException(tx, txe,
            TransactionalExecutor.Code.BeginFailure);

    }

    Object rs = null;
    try {

        // Do Your Business
        rs = business.execute();

    } catch (Throwable ex) {

        // 3. any business exception, rollback.
        try {
            tx.rollback();

            // 3.1 Successfully rolled back
            throw new TransactionalExecutor.ExecutionException(tx, TransactionalExecutor.Code.RollbackDone, ex);

        } catch (TransactionException txe) {
            // 3.2 Failed to rollback
            throw new TransactionalExecutor.ExecutionException(tx, txe,
                TransactionalExecutor.Code.RollbackFailure, ex);

        }

    }

    // 4. everything is fine, commit.
    try {
        tx.commit();

    } catch (TransactionException txe) {
        // 4.1 Failed to commit
        throw new TransactionalExecutor.ExecutionException(tx, txe,
            TransactionalExecutor.Code.CommitFailure);

    }
    return rs;
}这里就很明显的说明了实现的逻辑

GAME OVER~

发布了85 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/New_CJ/article/details/86609633