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把异常注释掉,发现库存,账户对应减少,并产生一条订单数据
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~