您的位置:首页 > Web前端

分布式事务解决方案Seata(Fescar)--记录个人学习的过程

2019-06-01 17:29 851 查看

 

seata服务的客户端的下载地址https://github.com/seata/seata/releases选择一个自己需要的版本

源码地址:https://github.com/seata/seata

seata Demo地址:https://github.com/seata/seata-samples

seata原名feacar,在0.5版本之后改名seata。

下面是官网的环境搭建:

用例:

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

              存储服务:扣除给定商品的存储数量。

             订单服务:根据购买请求创建订单。

             帐户服务:借记用户帐户的余额。

StorageService

[code]public interface StorageService {

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

OrderService

[code]public interface OrderService {

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

AccountService

[code]public interface AccountService {

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

Main business logic

[code]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);
}
}

 

 

[code]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);
}

SEATA分布式事务解决方案

 

使用方式

我们只需要一个

@GlobalTransactional
关于业务方法的注释:

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

上面是官网介绍的Seata的简单使用,下面记录一下自己的实践过程

数据库准备

[code]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;

 

 Demo下载

从GitHub上下载现成的demo:

下载地址:https://github.com/seata/seata-samples

打开效果如下:

这里我们可以看到seata提供了多种版本的测试demo我选择了第一种,spring+dubbo的方式

本地环境配置

方式1

下载地址:https://github.com/seata/seata/releases

下载对应的服务器客户端,我下载的是Windows环境下的

双击bin目录下的fescar-server.bat,启动服务。

2方式2

下载源码服务,启动源码服务

下载地址:https://github.com/seata/seata

源码结构如下:

Server中的main方法是他的启动方法,启动服务,运行main方法即可。

在这个main方法 中,我们可以看到他的端口都是写死的,如果需要更改客户端的端口需要重新将服务打包。

源码中的体现如下:

这两种方式我都尝试了,由于seata的版本和demo也是对应的,请选择合适的版本。

 

 

项目服务启动:

seata的用法:在业务层加上 

[code]@GlobalTransactional

启动顺序:

  • 启动DubboAccountServiceStarter
  • 启动DubboStorageServiceStarter
  • 启动DubboOrderServiceStarter
  •  
  • 运行DubboBusinessTester  

最后启动DubboBusinessTester  进行测试。

期望的结果,如果异常了,事务就回滚,数据库数据不更改。

业务代码如下:

结果是可以保证事务的回滚,如果将注解去掉数据库数据会产生脏数据,库存减少,但是程序异常,订单没用下成功。最终不能保证数据的一致性。

上面是seata的整体使用情况,用起来很简单,下面记录一下自己对seata的理解。

我们下载的客户端的ip,端口默认是本地的8091,,如过我们需要更改服务的ip和端口号需要通过重新更改server的源码地址,再重新打。

在我们项目的的客户端和seata的连接过程中,也都是使用的默认的端口号:

由于我个人在很久之前就下载过这个demo今天新下载的客户端服务,版本是最新的,版本不一致报了一个错误:

io.netty.handler.codec.DecoderException: java.nio.BufferUnderflowException

这个问题是由于版本的问题导致。

下面是seata的在linux的安装过程,我也没用安装,这里记录一下,方便以后自己需要。

地址:https://www.cnblogs.com/wintersoft/p/10548177.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: