Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA
和 XA 事务模式,为用户打造一站式的分布式解决方案。

中文官方站点:https://seata.io/zh-cn/
seata github开源地址:https://github.com/seata

本地事务

在计算机系统中,更多的是通过关系型数据库来控制事务,这是利用数据库本身的事务特性来实现的,因此叫数据库事务,由于应用主要靠关系数据库来控制事务,而数据库通常和应用在同一个服务器,所以基于关系型数据库的事务又被称为本地事务。

数据库事务的四大特性:ACID

A(Atomic):原子性构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成 功部分失败的情况。
C(Consistency):一致性,**在事务执行前后,数据库的一致性约束没有被破坏。**比如:张三向李四转 100元,转账前和转账后的数据是正确状态这叫一致性,如果出现张三转出 100 元,李四账户没有增加 100 元这就出现了数据错误,就没有达到一致性。
I(Isolation):隔离性,**数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其他事务的运行过程的中间状态。**通过配置事务隔离级别可以比避免脏读、重复读问题。
D(Durability):持久性事务完成之后,该事务对数据的更改会持久到数据库,且不会被回滚。

数据库事务在实现时会将一次事务的所有操作全部纳入到一个不可分割的执行单元,该执行单元的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都将导致整个事务的回滚。

分布式事务

随着互联网的快速发展,软件系统由原来的单体应用转变为分布式应用
分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务,
例如用户注册送积分事务、创建订单减库存事务,银行转账事务等都是分布式事务。

阿里分布式事务框架Seata案例

1、整体项目结构如下图:

2、数据库设计
新建两个数据库,分别是 db_order (订单数据库), db_account (账户数据库),db_order 数据库里面新建表 t_order 订单表:


3、搭建父级项目 seatatest
导入依赖:

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><druid.version>1.1.10</druid.version><spring-cloud.version>2020.0.4</spring-cloud.version><springboot.version>2.5.5</springboot.version><springcloudalibaba.version>2021.1</springcloudalibaba.version><fastjson.version>1.2.35</fastjson.version><commons-lang3.version>3.6</commons-lang3.version><seata-common.version>1.0-SNAPSHOT</seata-common.version><mybatis.version>2.2.0</mybatis.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${springboot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${springcloudalibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons-lang3.version}</version></dependency><dependency><groupId>com.java1234</groupId><artifactId>seata-common</artifactId><version>${seata-common.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency></dependencies></dependencyManagement>

4、seata-common子项目搭建
导入依赖:

<dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.4.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId></dependency><!-- spring boot redis 缓存引入 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- lettuce pool 缓存连接池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies>

用户账户实体类:

public class Account {private Integer id; // 编号private Integer userId; // 用户编号private Integer balance; // 账户余额private String remark; // 备注public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public Integer getBalance() {return balance;}public void setBalance(Integer balance) {this.balance = balance;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}
}

订单实体类:

public class Order {private Integer id; // 编号private String orderNo; // 订单号private Integer userId; // 用户编号private Integer count; // 购买数量private Integer amount; // 购买金额private String remark; // 备注public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getOrderNo() {return orderNo;}public void setOrderNo(String orderNo) {this.orderNo = orderNo;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}public Integer getAmount() {return amount;}public void setAmount(Integer amount) {this.amount = amount;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}
}

5、seata-order子项目搭建
导入依赖:

   <dependency><groupId>com.java1234</groupId><artifactId>seata-common</artifactId></dependency>

application.yml配置:

server:port: 8081servlet:context-path: /spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_order?serverTimezone=Asia/Shanghaiusername: rootpassword: rootcloud:nacos:discovery:server-addr: 127.0.0.1:8848alibaba:seata:tx-service-group: my_test_tx_groupapplication:name: seata-ordermybatis:mapper-locations: classpath:mybatis/mapper/*.xmlseata:service:vgroup-mapping:my_test_tx_group: defaultgrouplist:default: 127.0.0.1:8091enable-degrade: falsedisable-global-transaction: false

mapper层

public interface OrderMapper {/*** 创建订单* @param order*/void createOrder(Order order);
}

service层:

public interface OrderService {/*** 创建订单* @param order*/void createOrder(Order order);
}

service实现类:

@Service("orderService")
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Overridepublic void createOrder(Order order) {orderMapper.createOrder(order);}
}

controller层:

@RestController
@RequestMapping("/seata")
public class OrderController {@Autowiredprivate OrderService orderService;/*** 创建订单* @param order* @return*/@PostMapping("/createOrder")public boolean createOrder(@RequestBody Order order){System.out.println("order:"+order);order.setOrderNo(UUID.randomUUID().toString());  // 生成订单IDorderService.createOrder(order);return true;}
}

mapperxml层:

 <select id="createOrder" parameterType="com.java1234.entity.Order" >insert into t_order values(null,#{orderNo},#{userId},#{count},#{amount},#{remark})</select>

5、seata-account子项目搭建
导入依赖:

    <dependency><groupId>com.java1234</groupId><artifactId>seata-common</artifactId></dependency>

application.yml配置:

server:port: 8082servlet:context-path: /spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_account?serverTimezone=Asia/Shanghaiusername: rootpassword: rootcloud:nacos:discovery:server-addr: 127.0.0.1:8848alibaba:seata:tx-service-group: my_test_tx_groupapplication:name: seata-accountmybatis:mapper-locations: classpath:mybatis/mapper/*.xmlseata:config:type: nacosnacos:server-addr: 127.0.0.1:8848group: SEATA_GROUPnamespace: ""registry:type: nacosnacos:application: seata-serverserver-addr: 127.0.0.1:8848group: "SEATA_GROUP"namespace: ""

mapperxml:

    <select id="decrease" parameterType="Map" >UPDATE t_account SET balance=balance-#{amount} WHERE userId=#{userId}</select>

mapper:

@Mapper
public interface AccountMapper {/*** 账户扣钱*/void decrease(Map map);
}

service:

public interface AccountService {/*** 账户扣钱*/void decrease(Map map);
}

service实现类:

@Service("accountService")
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountMapper accountMapper;@Overridepublic void decrease(Map map) {accountMapper.decrease(map);}
}

controller层:

@RestController
@RequestMapping("/account")
public class AccountController {@Autowiredprivate AccountService accountService;/*** 给指定用户账户扣钱* @param amount* @param userId* @return*/@PostMapping("/decrease")public boolean decrease(@RequestParam("amount")Integer amount, @RequestParam("userId")Integer userId){System.out.println("amount:"+amount+",userId:"+userId);Map<String,Object> map=new HashMap<>();map.put("amount",amount);map.put("userId",userId);accountService.decrease(map);return true;}
}

启动类:

@SpringBootApplication
@MapperScan("com.java1234.mapper")
@EnableDiscoveryClient
public class AccountApplication {public static void main(String[] args) {SpringApplication.run(AccountApplication.class, args);}
}

6、seata-web子项目搭建
导入依赖:

    <dependencies><dependency><groupId>com.java1234</groupId><artifactId>seata-common</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency></dependencies>

application.yml配置类:

server:port: 80servlet:context-path: /spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848alibaba:seata:tx-service-group: my_test_tx_groupapplication:name: seata-webseata:service:vgroup-mapping:my_test_tx_group: defaultgrouplist:default: 127.0.0.1:8091enable-degrade: falsedisable-global-transaction: false

controller层:

@RestController
public class WebController {@Autowiredprivate OrderFeignService orderFeignService;@Autowiredprivate AccountFeignService  accountFeignService;/*** 下单 1,创建订单 2,账户扣钱* @param order* @return*/@PostMapping("/shopping")@GlobalTransactionalpublic boolean shopping(Order order){orderFeignService.createOrder(order); // 创建订单accountFeignService.decrease(order.getAmount(),order.getUserId()); // 账户扣钱return true;}
}

feign层:

@FeignClient("seata-account")
public interface AccountFeignService {/*** 账号扣钱* @param amount* @param userId* @return*/@PostMapping("/account/decrease")public boolean decrease(@RequestParam("amount")Integer amount, @RequestParam("userId")Integer userId);}
@FeignClient("seata-order")
public interface OrderFeignService {/*** 创建订单* @param order* @return*/@PostMapping("/seata/createOrder")public boolean createOrder(@RequestBody Order order);}

7、项目启动:
先启动nacos服务注册中心

测试接口:http://localhost/shopping
postman测试:

模拟抛出异常时:

此时数据库中:生成订单,且相应账户余额增加及减少


8、CAP理论
CAP理论:一个分布式系统不可能同时满足一致性,可用性和分区容错性这个三个基本需求,最多只能
同时满足其中两项

一致性©:数据在多个副本之间是否能够保持一致的特性。
可用性(A):是指系统提供的服务必须一致处于可用状态,对于每一个用户的请求总是在有限的时间内返 回结果,超过时间就认为系统是不可用的
分区容错性§:分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和 可用性的服务,除非整个网络环境都发生故障。

CAP定理的应用

放弃P(CA):如果希望能够避免系统出现分区容错性问题,一种较为简单的做法就是将所有的数据(或者 是与事物先相关的数据)都放在一个分布式节点上,这样虽然无法保证100%系统不会出错,但至少不会 碰到由于网络分区带来的负面影响
放弃A(CP):其做法是一旦系统遇到网络分区或其他故障时,那受到影响的服务需要等待一定的时间,应 用等待期间系统无法对外提供正常的服务,即不可用
**放弃C(AP)

阿里分布式事务框架Seata相关推荐

  1. 阿里分布式事务框架Seata原理解析

    阿里分布式事务框架Seata原理解析 作者:伊凡的一天 链接:https://www.jianshu.com/p/044e95223a17 Seata框架是一个业务层的XA(两阶段提交)解决方案.在理 ...

  2. 老板现在喊我大哥,原因是我用阿里分布式事务框架Seata解决了长久以来困扰公司的分布式事务问题

    大家好,我是曹尼玛 从大学毕业5年,一直努力学习,努力工作,追求新技术,不保守. 上个月我来到一家新公司上班,月薪20K,这家公司老板人很好,对员工很关爱,公司氛围不错,同事们也努力把公司项目搞搞好. ...

  3. 阿里分布式事务框架Seata集成详情

    大家好,我是曹尼玛 从大学毕业5年,一直努力学习,努力工作,追求新技术,不保守. 上个月我来到一家新公司上班,月薪20K,这家公司老板人很好,对员工很关爱,公司氛围不错,同事们也努力把公司项目搞搞好. ...

  4. 阿里分布式事务框架Seata,AT模式原理解析

    什么是分布式事务 如今在分布式技术盛行下,许多公司都已经在使用分布式技术了,虽然分布式技术给我们项目带来了三高(高可用,高扩展,高性能)等优点,但是缺点也很明显,分布式项目一般都是分服务开发,且多个服 ...

  5. 分布式事务seata只支持MySQL_阿里分布式事务框架Seata原理解析

    Seata框架是一个业务层的XA(两阶段提交)解决方案.在理解Seata分布式事务机制前,我们先回顾一下数据库层面的XA方案. 1. MySQL XA方案 MySQL从5.7开始加入了分布式事务的支持 ...

  6. 阿里开源一站式分布式事务框架seata源码分析(AT模式下TM与RM分析)

    序言: 对于阿里开源分布式事务框架seata的详细了解可以参考官网,这里不会详细介绍.本章只会介绍seata中AT模式的源码分析(对阿seata有一定了解或者成功完成过demo). seata中一个事 ...

  7. 关于分布式事务: 阿里开源的分布式事务框架 Seata 和 LCN的分析

    之前使用过LCN分布式事务, 最近看到面试者简历中另一种方案 Seata, 通过它来在实战中解决分布式事务的问题.故 去简单了解了一下Seata是什么, 和LCN的区别在哪里, 如果是你 你怎么选择解 ...

  8. 分布式事务框架seata介绍

    分布式事务框架seata介绍 一 . 事务特性(ACID) 1.原子性(A) 在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态.对于事务在执行中发生错误,所有的操作都会被回滚,整个事务 ...

  9. 分布式事务框架Seata

    分布式事务框架Seata     sei达 一. 分布式事务前言 1. 数据库管理系统中事务(transaction)的四个特性:简称ACID(这种特性简称刚性事物) 原子性(Atomicity):原 ...

最新文章

  1. 腾讯首位17级杰出科学家诞生:腾讯AI Lab负责人张正友
  2. 直击KubeCon 2018 |云原生正在改变你的衣食住行
  3. Linux下编译vtk的java版本,vtk在linux下的安裝(12月8日更新)
  4. 火爆数据圈的数据分析工具,快速上手动态报表就是这么简单
  5. Django运行SQL语句
  6. android 根据资源名称,如何在Android中按名称访问可绘制资源
  7. java addbatch_使用addBatch java时丢失数据
  8. 洪水填充算法_区域填充算法和多边形填充的扫描线算法
  9. 显著性测试(Friedman test, Post-hoc Nimenyi test以及可视化)
  10. 计算机应用网络工程师的英文名字,网络工程师英文简历
  11. Lodop打印控件的学习
  12. (研究向)如何使用Windows任务管理器看BadApple
  13. 【时间序列】时序分析之移动平均-python实战
  14. 市场对计算机专业的需求是怎么样的,计算机专业的行业需求分析
  15. java 基础 String str= “abc god 中国 java“ 反转每个单词 结果: “cba dog 国中
  16. Android 录制手机内部声音(screen recorder)framework层问题分析
  17. 网站的服务器ip变动,网站切换服务器IP,如何快速快速刷新DNS以获得测试?
  18. 2020淘宝平台搜索规则变化和调整,搜索转化率如何提升
  19. 【一种利用插值验证的FL隐私保护框架】VFL: A Verifiable Federated Learning
  20. 学生学籍管理系统jsp源代码 MySql_jsp学籍管理系统——mysql+java web

热门文章

  1. java 音频转为wav格式标准音频 | Java工具类
  2. 补天 公益src 爬虫
  3. 深入理解JDK动态代理原理,使用javassist动手写一个动态代理框架
  4. 英国CodaOctopus公司的Echoscope®实时3D声呐
  5. 计算机java实训报告,计算机Java实训报告.doc
  6. 修改rubymine字体大小
  7. 电脑永久删除文件怎么找回来?分享一种数据恢复方法
  8. 【网络编程】python网络编程多线程实现
  9. CESS 机制详解(1):多层网络架构设计
  10. wow 人物初次创建进入游戏时的世界公告