分布式事务fescar(二)

/ 开源软件 / 没有评论 / 1396浏览

快速上手

微服务示例。

  1. 启动fescar-server
    下载发布包并解压缩。下载地址:https://github.com/alibaba/fescar/releases
    cd bin,运行启动脚本
    sh fescar-server.sh $port $dirPath
    示例:sh fescar-server.sh /Users/min.ji/Downloads/data/
    $port是netty-server监听的端口,$dirPath是一个已存在的路径,可以存储交易操作和恢复交易。

  2. 用例
    用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

alt
StorageService

public interface StorageService {

    /**
     * deduct storage count
     */
    void deduct(String commodityCode, int count);
}

OrderService

public interface OrderService {

    /**
     * create order
     */
    Order create(String userId, String commodityCode, int orderCount);
}

AccountService

public interface AccountService {

    /**
     * debit balance of user's account
     */
    void debit(String userId, int money);
}

主要业务逻辑

public class BusinessServiceImpl implements BusinessService {

    private StorageService storageService;

    private OrderService orderService;

    /**
     * purchase
     */
    public void purchase(String userId, String commodityCode, int orderCount) {

        storageService.deduct(commodityCode, orderCount);

        orderService.create(userId, commodityCode, orderCount);
    }
}

public class OrderServiceImpl implements OrderService {

    private OrderDAO orderDAO;

    private AccountService accountService;

    public Order create(String userId, String commodityCode, int orderCount) {

        int orderMoney = calculate(commodityCode, orderCount);

        accountService.debit(userId, orderMoney);

        Order order = new Order();
        order.userId = userId;
        order.commodityCode = commodityCode;
        order.count = orderCount;
        order.money = orderMoney;

        // INSERT INTO orders ...
        return orderDAO.insert(order);
    }

FESCAR的分布式事务解决方案

alt

我们仅仅需要在业务方法上添加一个@GlobalTransactional注解:

   @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount) {
        ......
    }

Dubbo + FESCAR示例

第1步:设置数据库
要求:带有InnoDB引擎的MySQL。
注意:实际上,示例用例中的3个服务应该有3个数据库。但是,我们只需创建一个数据库并配置3个数据源即可。

使用刚刚创建的数据库URL /用户名/密码修改 Spring XML。

dubbo-account-service.xml dubbo-order-service.xml dubbo-storage-service.xml

     <property name="url" value="jdbc:mysql://x.x.x.x:3306/xxx" />
     <property name="username" value="xxx" />
     <property name="password" value="xxx" />

第2步:创建UNDO_LOG表
FESCAR AT模式下需要存在UNDO_LOG表。

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_unionkey` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=159 DEFAULT CHARSET=utf8

第3步:创建示例业务表

DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

第4步:运行示例