一、简介

官网地址:http://seata.io/zh-cn/

1,概念

  Seata是一款开源的分布式事务解决方案,致力于在微服务架构在提供高性能和简单一样的分布式事务服务。

2,处理过程

  Transaction ID XID:全局唯一的事务ID

  Transaction Coordinator(TC) :维护全局和分支事务的状态,驱动全局事务提交或回滚。

  Transaction  Manager(TM) :定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  Resource Manager(RM) :管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

  1. TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID
  2. XID在微服务调用链路的上下文中传播
  3. RM向TC注册分支事务,将其纳入XID对应全局事务的管辖
  4. TM向TC发起针对XID的全局提交或回滚决议
  5. TC调度XID下管辖的全部分支事务完成提交或回滚请求

二、Seata-Server的安装

1,下载

  http://seata.io/zh-cn/blog/download.html 选择指定版本下载(我这里用的是0.9.0)

2,修改配置文件

  修改seata/conf/file.conf

#将service中修改group
vgroup_mapping.my_test_tx_group = "my_group"
#将store模块修改为db并修改数据连接,将conf目录下的db_store.sql文件导入到数据库中
mode = "db"
db {
datasource = "dbcp"
db-type = "mysql"
driver-class-name = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "root"
password = "123456"
}

  修改seata/conf/registry.conf

registry {
type = "nacos"
nacos {
serverAddr = "localhost:8848"
namespace = ""
cluster = "default"
}

三、Seata的应用

1,订单服务

源码:seata-order-service2001

a,配置pom

<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<artifactId>seata-all</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>0.9.0</version>
</dependency>
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--web-actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--mysql-druid-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>

b,配置yaml

server:
port: 2001 spring:
application:
name: seata-order-service
cloud:
alibaba:
seata:
#自定义事务组名称需要与seata-server中的对应
tx-service-group: my_group
nacos:
discovery:
server-addr: localhost:8848
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/seata_order
username: root
password: 123456 feign:
hystrix:
enabled: false logging:
level:
io:
seata: info mybatis:
mapperLocations: classpath:mapper/*.xml

c,添加file.conf(与seata-server配置相同)

transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
#thread factory for netty
thread-factory {
boss-thread-prefix = "NettyBoss"
worker-thread-prefix = "NettyServerNIOWorker"
server-executor-thread-prefix = "NettyServerBizHandler"
share-boss-worker = false
client-selector-thread-prefix = "NettyClientSelector"
client-selector-thread-size = 1
client-worker-thread-prefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
boss-thread-size = 1
#auto default pin or 8
worker-thread-size = 8
}
shutdown {
# when destroy server, wait seconds
wait = 3
}
serialization = "seata"
compressor = "none"
} service { vgroup_mapping.my_group = "default" default.grouplist = "127.0.0.1:8091"
enableDegrade = false
disable = false
max.commit.retry.timeout = "-1"
max.rollback.retry.timeout = "-1"
disableGlobalTransaction = false
} client {
async.commit.buffer.limit = 10000
lock {
retry.internal = 10
retry.times = 30
}
report.retry.count = 5
tm.commit.retry.count = 1
tm.rollback.retry.count = 1
} ## transaction log store
store {
## store mode: file、db
mode = "db" ## file store
file {
dir = "sessionStore" # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
max-branch-session-size = 16384
# globe session size , if exceeded throws exceptions
max-global-session-size = 512
# file buffer size , if exceeded allocate new buffer
file-write-buffer-cache-size = 16384
# when recover batch read size
session.reload.read_size = 100
# async, sync
flush-disk-mode = async
} ## database store
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
datasource = "dbcp"
## mysql/oracle/h2/oceanbase etc.
db-type = "mysql"
driver-class-name = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "root"
password = "123456"
min-conn = 1
max-conn = 3
global.table = "global_table"
branch.table = "branch_table"
lock-table = "lock_table"
query-limit = 100
}
}
lock {
## the lock store mode: local、remote
mode = "remote" local {
## store locks in user's database
} remote {
## store locks in the seata's server
}
}
recovery {
#schedule committing retry period in milliseconds
committing-retry-period = 1000
#schedule asyn committing retry period in milliseconds
asyn-committing-retry-period = 1000
#schedule rollbacking retry period in milliseconds
rollbacking-retry-period = 1000
#schedule timeout retry period in milliseconds
timeout-retry-period = 1000
} transaction {
undo.data.validation = true
undo.log.serialization = "jackson"
undo.log.save.days = 7
#schedule delete expired undo_log in milliseconds
undo.log.delete.period = 86400000
undo.log.table = "undo_log"
} ## metrics settings
metrics {
enabled = false
registry-type = "compact"
# multi exporters use comma divided
exporter-list = "prometheus"
exporter-prometheus-port = 9898
} support {
## spring
spring {
# auto proxy the DataSource bean
datasource.autoproxy = false
}
}

d,添加registry.conf(与seata-server的配置相同)

registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos" nacos {
serverAddr = "localhost:8848"
namespace = ""
cluster = "default"
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = "0"
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
} config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file" nacos {
serverAddr = "localhost"
namespace = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
app.id = "seata-server"
apollo.meta = "http://192.168.1.204:8801"
}
zk {
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}

e,fegin调用(这里以其中一个account为例)

@FeignClient(value = "seata-account-service")
public interface AccountService { @RequestMapping("/account/decrease")
public CommonResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money); }

f,事务service

@Slf4j
@Service
public class OrderServiceImpl implements OrderService { @Autowired
OrderDao orderDao;
@Autowired
AccountService accountService;
@Autowired
StorageService storageService; @Override
@GlobalTransactional(name = "my-order-test",rollbackFor = Exception.class) //加注解使用全局的事务,name 为事务名称不重复就行
public Long create(Order order) {
log.info("=========================下订单,开始");
orderDao.create(order);
log.info("=========================下订单,完成"); log.info("=========================减库存,开始");
storageService.decrease(order.getProductId(), order.getCount());
log.info("=========================减库存,完成"); log.info("=========================减积分,开始");
accountService.decrease(order.getUserId(), order.getMoney());
log.info("=========================减积分,完成"); log.info("=========================订单状态修改,开始");
orderDao.update(order.getId(),1);
log.info("=========================订单状态修改,完成"); return order.getId();
}
}

g,启动类

2,库存服务

源码:seata-storage-service2002

  与订单服务中的a,b,c,d,g配置步骤相同

3,账户服务

源码:seata-account-service2003

  与库存服务的配置步骤相同

Spring Cloud Alibaba Seata的更多相关文章

  1. Spring Cloud Alibaba | 微服务分布式事务之Seata

    Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Green ...

  2. Spring Cloud Alibaba 初体验(六) Seata 及结合 MyBatis 与 MyBatis-Plus 的使用

    一.下载与运行 本文使用 Seata 1.1.0:https://github.com/seata/seata/releases Windows 环境下双击 bin/seata-server.bat ...

  3. 厉害了,Spring Cloud Alibaba 发布 GA 版本!

    ? 小马哥 & Josh Long ? 喜欢写一首诗一般的代码,更喜欢和你共同 code review,英雄的相惜,犹如时间沉淀下来的对话,历久方弥新. 相见如故,@杭州. 4 月 18 日, ...

  4. Spring 社区的唯一一个国产开源项目 - Spring Cloud Alibaba 毕业了

    阿里妹导读:一年多前,Java 界最近发生了一件大事,阿里开源 Spring Cloud Alibaba,并推出首个预览版.Spring Cloud 本身是一套微服务规范,并不是一个拿来即可用的框架, ...

  5. Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!

    在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也终于发布了最新的版本.该版本距离上一次发布,过去了整整4个月!下面就随我一起看看,这个大家期待已久的版本都有哪些 ...

  6. Spring Cloud Alibaba | 序言

    目录 Spring Cloud Alibaba | 序言 1. Spring Cloud Alibaba是什么? 2. 主要功能 3. 组件 4. 版本说明 4.1 版本依赖关系 4.2 组件版本关系 ...

  7. spring cloud alibaba 简介

    ### Spring Cloud Alibaba [官方github地址](https://github.com/alibaba/spring-cloud-alibaba) Spring Cloud ...

  8. Spring Cloud Alibaba 新一代微服务解决方案

    本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...

  9. Spring Cloud Alibaba 从孵化到 "挂牌" 之旅

    背景 2014 年,Spring Boot 1.0 发布.Spring Boot 的发布绝对是 Pivotal 历史上具有里程碑意义的事件,它让我们能够非常简便地开发 Spring 应用,屏蔽了各种配 ...

随机推荐

  1. ASP.NET Core新书终于上市,完成今年一个目标,赠书活动

    2018年.NET Core 2.0发布后,开始逐步学习.NET Core 并逐步在新的项目中使用ASP.NET Core.并且零零散散写的写了将近30篇学习笔记发到园子里,包括ASP.NET Cor ...

  2. 容器云平台No.3~kubernetes使用

    今天是是第三篇,接着上一篇继续 首先,通过kubectl可以看到,三个节点都正常运行 [root@k8s-master001 ~]# kubectl get no NAME STATUS ROLES ...

  3. Flutter学习一之环境搭建

    MacOS上搭建Flutter开发环境 1.flutter官网下载最新的安装包,https://flutter.io/sdk-archive/#macos 2.解压安装包到你想安装的目录.直接解压或者 ...

  4. 朴素版和堆优化版dijkstra和朴素版prim算法比较

    1.dijkstra 时间复杂度:O(n^2) n次迭代,每次找到距离集合S最短的点 每次迭代要用找到的点t来更新其他点到S的最短距离. #include<iostream> #inclu ...

  5. 【Flutter 实战】大量复杂数据持久化

    老孟导读:上一篇文章讲解了 Android 和 iOS 的文件目录系统,此篇文章讲解如何使用 SQLite 保存数据. 欢迎大家投稿:http://laomengit.com/plan/Contrib ...

  6. Mysql的ONLY_FULL_GROUP_BY

    今天在测试环境遇到一个问题,本地测试是没有问题,在测试环境sql报错了: nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntax ...

  7. 数据库图形表Navicat Premium

    1.什么是数据库? 存储数据,为了方便查询和使用 web时代使用最广泛的关系型数据库 2.历史: 瑞典公司开发,卖给SUN,SUN又卖给ORACLE 开源,免费,支持多平台 3.数据库图形表Navic ...

  8. Gitlab集成Sonarqube自动检测代码并发送报告给提交者

    使用gitlab-ci.sonarqube.sonar-scanner 实现如下功能 1.一旦提交代码就进行代码质量检测 2. 发送检测报告邮件给提交者 先来看下最终结果,邮件中有检测报告,具体bug ...

  9. Presto 标量函数注册和调用过程简述

    在Presto 函数开发一文中已经介绍过如何进行函数开发,本文主要讲述标量函数(Scalar Function)实现之后,是如何在Presto内部进行注册和被调用的.主要讲述标量函数是因为:三类函数的 ...

  10. c#后台代码请求访问api接口

    前言:最近公司项目与外部api接口对接较多 ,写下自己的代码总结.介绍两种访问方式(HttpClient.HttpWebRequest) 一.HttpWebRequest 访问Api private ...