分布式事务框架seata介绍

一 、 事务特性(ACID)

1、原子性(A)
在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。对于事务在执行中发生错误,所有的操作都会被回滚,整个事务就像从没被执行过一样。

2、一致性(C)
事务的执行必须保证系统的一致性

3、隔离性(I)
所谓的隔离性就是说,事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。

4、持久性(D)
所谓的持久性,就是说一单事务完成了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停电,系统宕机也是如此。

这种特性简称刚性事物

二、事务隔离级别

1、脏读:事务T1读取到事务T2修改了但是还未提交的数据,之后事务T2又回滚其更新操作,导致事务T1读到的是脏数据。

2、不可重复读:事务T1读取某个数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。

3、幻影读:事务T1读取在读取某范围数据时,事务T2又插入一条数据,当事务T1再次数据这个范围数据时发现不一样了,出现了一些“幻影行”。

不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

幻读和不可重复读的异同:都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体。

三、分布式事务

1、概念

 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

2、CPA理论

 CAP由Eric Brewer在2000年PODC会议上提出[1][2],是Eric Brewer在Inktomi[3]期间研发搜索引擎、分布式web缓存时得出的关于数据一致性(consistency)、服务可用性(availability)、分区容错性(partition-tolerance)的猜想:

(1)数据一致性(consistency):如果系统对一个写操作返回成功,那么之后的读请求都必须读到这个新数据;如果返回失败,那么所有读操作都不能读到这个数据,对调用者而言数据具有强一致性(strong consistency) (又叫原子性 atomic、线性一致性 linearizable consistency)(2)服务可用性(availability):所有读写请求在一定时间内得到响应,可终止、不会一直等待(3)分区容错性(partition-tolerance):在网络分区的情况下,被分隔的节点仍能正常对外服务、

3、Base理论

  BASE理论是指,Basically Available(基本可用)、Soft-state( 软状态/柔性事务)、Eventual Consistency(最终一致性)。是基于CAP定理演化而来,是对CAP中一致性和可用性权衡的结果。核心思想:即使无法做到强一致性,但每个业务根据自身的特点,采用适当的方式来使系统达到最终一致性。

1、基本可用:指分布式系统在出现故障的时候,允许损失部分可用性,保证核心可用。但不等价于不可用。比如:搜索引擎0.5秒返回查询结果,但由于故障,2秒响应查询结果;网页访问过大时,部分用户提供降级服务,等。2、软状态:软状态是指允许系统存在中间状态,并且该中间状态不会影响系统整体可用性。即允许系统在不同节点间副本同步的时候存在延时。3、最终一致性:系统中的所有数据副本经过一定时间后,最终能够达到一致的状态,不需要实时保证系统数据的强一致性。最终一致性是弱一致性的一种特殊情况。BASE理论面向的是大型高可用可扩展的分布式系统,通过牺牲强一致性来获得可用性。ACID是传统数据库常用的概念设计,追求强一致性模型

四、微服务中的分布式事务问题

 让我们想象一下传统的单个应用程序。它的业务由3个模块组成。他们使用单个本地数据源。

自然,本地事务将保证数据的强一致性。

 微服务架构已发生了变化。上面提到的3个模块被设计为在3种不同数据源之上的3种服务。本地事务已经无法保证模块之间调用数据的一致性。

五、seata介绍?

1、Seata是阿里开发的一个用于微服务架构的高性能易使用的分布式事务框架。分布式事务是由一批分支事务组成的全局事务,通常分支事务只是本地事务。

2、Seata有3个基本组成部分:

  • **事务协调器(TC):**维护全局事务和分支事务的状态,驱动全局提交或回滚。

  • **事务管理器(TM):**用于开启全局事务、提交或者回滚全局事务,是全局事务的开启者。

  • **资源管理器(RM):**用于分支事务上的资源管理,向TC注册分支事务,上报分支事务的状态,接受TC的命令来提交或者回滚分支事务。

    3、Seata管理的分布式事务的典型生命周期:

(1)TM向TC请求发起一个全局事务,TC返回一个代表这个全局事务的XID。

(2)XID通过微服务的调用链传播。

(3)每个RM拿到XID后向TC发起一个分支事务,TC返回一个代表这个分支事务的XID。

(4)RM完成本地分支的业务,提交本地分支,并且报告给TC。

(5)全局事务调用链处理完毕,TM根据有无异常向TC发起全局事务的提交或者回滚。

(6)假设某个RM本地事务失败。该RM自身驱动本地事务回滚,并且报告给TC。

(7)TM检测到了某个分支事务失败,向TC发起全局事务回滚。

(8)TC给每一个RM发送消息,通知它们全部回滚。

(9)TC将全局事务回滚的结果发送给TM,全局事务结束。

六、demo简介

1.demo技术选型

  • 注册中心:eureka

  • 服务间调用:feign

  • 持久层:mybatis

  • 数据库:mysql 5.7.20

  • Springboot:2.1.7.RELEASE

  • Springcloud:Greenwich.SR2

  • jdk:1.8

  • seata:0.8

demo分为四个项目,单独启动。

  • eureka:作为注册中心
  • order:订单服务,用户下单后,会创建一个订单添加在order数据库,同时会扣减库存storage,扣减账户account;
  • storage:库存服务,用户扣减库存;
  • account:账户服务,用于扣减账户余额;

注:使用时版本需要相对应

order服务关键代码如下:

    @Override@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class) //此注解开启全局事务public void create(Order order) {//本地方法 创建订单orderDao.create(order);//远程方法 扣减库存storageApi.decrease(order.getProductId(),order.getCount());//远程方法 扣减账户余额  可在accountServiceImpl中模拟异常accountApi.decrease(order.getUserId(),order.getMoney());}

2.使用步骤

  • (1).拉取本demo代码;
  • (2).拉取seata-server;
  • (3).执行每个项目下的建表语句,resource下xx.sql文件;
  • (4).seata相关建表语句见下文说明;

3.seata server端配置信息修改

seata-server中,/conf目录下,有两个配置文件,需要结合自己的情况来修改:

(1).file.conf

 里面有事务组配置,锁配置,事务日志存储等相关配置信息,由于此demo使用db存储事务信息,我们这里要修改store中的配置:

## transaction log store
store {## store mode: file、dbmode = "db"   修改这里,表明事务信息用db存储## file store 当mode=db时,此部分配置就不生效了,这是mode=file的配置file {dir = "sessionStore"# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptionsmax-branch-session-size = 16384# globe session size , if exceeded throws exceptionsmax-global-session-size = 512# file buffer size , if exceeded allocate new bufferfile-write-buffer-cache-size = 16384# when recover batch read sizesession.reload.read_size = 100# async, syncflush-disk-mode = async}## database store  mode=db时,事务日志存储会存储在这个配置的数据库里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://116.62.62.26/seat-server"  修改这里user = "root"  修改这里password = "root"  修改这里min-conn = 1max-conn = 3global.table = "global_table"branch.table = "branch_table"lock-table = "lock_table"query-limit = 100}
}

 由于此demo我们使用db模式存储事务日志,所以,我们要创建三张表:global_table,branch_table,lock_table,建表sql在上面下载的seata-server的/conf/db_store.sql中;

 由于存储undo_log是在业务库中,所以在每个业务库中,还要创建undo_log表,建表sql在/conf/db_undo_log.sql中。

由于我自定义了事务组名称,所以这里也做了修改:

service {#vgroup->rgroupvgroup_mapping.fsp_tx_group = "default"  修改这里,fsp_tx_group这个事务组名称是我自定义的,一定要与client端的这个配置一致!否则会报错!#only support single nodedefault.grouplist = "127.0.0.1:8091"   此配置作用参考:https://blog.csdn.net/weixin_39800144/article/details/100726116#degrade current not supportenableDegrade = false#disabledisable = false#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanentmax.commit.retry.timeout = "-1"max.rollback.retry.timeout = "-1"
}

 其他的可以先使用默认值。

(2).registry.conf

 registry{}中是注册中心相关配置,config{}中是配置中心相关配置。seata中,注册中心和配置中心是分开实现的,是两个东西。

我们这里用eureka作注册中心,所以,只用修改registry{}中的:

registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "eureka"  修改这里,指明注册中心使用什么nacos {serverAddr = "localhost"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 = 6000connect.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"}
}

 其他的配置可以暂时使用默认值。

(3) 如果是在windows下启动seata-server,现在已经完成配置修改了,等eureka启动后,就可以启动seata-server了:执行/bin/seata-server.bat即可。
(4)用开发工具启动如下类就可以

4、client端相关配置

1.普通配置

client端的几个服务,都是普通的springboot整合了springCloud组件的正常服务,所以,你需要配置eureka,数据库,mapper扫描等,即使不使用seata,你也需要做,这里不做特殊说明,看代码就好。

2.特殊配置
1.application.yml

以order服务为例,除了常规配置外,这里还要配置下事务组信息:

spring:application:name: order-servercloud:alibaba:seata:tx-service-group: fsp_tx_group  这个fsp_tx_group自定义命名很重要,server,client都要保持一致
2.file.conf

自己新建的项目是没有这个配置文件的,copy过来,修改下面配置:

service {#vgroup->rgroupvgroup_mapping.fsp_tx_group = "default"   这个fsp_tx_group自定义命名很重要,server,client都要保持一致#only support single nodedefault.grouplist = "127.0.0.1:8091"#degrade current not supportenableDegrade = false#disabledisable = falsedisableGlobalTransaction = false
}
3.registry.conf

使用eureka做注册中心,仅需要修改eureka的配置即可:

registry {# file 、nacos 、eureka、redis、zktype = "eureka"   修改这里nacos {serverAddr = "localhost"namespace = "public"cluster = "default"}eureka {serviceUrl = "http://localhost:8761/eureka"  修改这里application = "default"weight = "1"}redis {serverAddr = "localhost:6381"db = "0"}zk {cluster = "default"serverAddr = "127.0.0.1:2181"session.timeout = 6000connect.timeout = 2000}file {name = "file.conf"}
}

其他的使用默认值就好。

3.数据源代理

这个是要特别注意的地方,seata对数据源做了代理和接管,在每个参与分布式事务的服务中,都要做如下配置:

/*** 数据源代理*/
@Configuration
public class DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource druidDataSource(){DruidDataSource druidDataSource = new DruidDataSource();return druidDataSource;}@Primary@Bean("dataSource")public DataSourceProxy dataSource(DataSource druidDataSource){return new DataSourceProxy(druidDataSource);}@Beanpublic SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSourceProxy);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/*.xml"));sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());return sqlSessionFactoryBean.getObject();}}

5.启动测试

  • (1).启动eureka;

  • (2).启动seata-server;

  • (3).启动order,storage,account服务;

    DEFAULT为seata服务的默认名字,也可通过修改配置文件自定义名字

  • (5).访问:http://localhost:8080/order/create?userId=1&productId=1&count=10&money=100

然后可以模拟正常情况,异常情况,超时情况等,观察数据库即可,发现事务控制成功

6.模拟异常情况

  • (1)账户服务抛异常
  /*** 扣减账户余额* @param userId 用户id* @param money 金额*/@Overridepublic void decrease(Long userId, BigDecimal money) {LOGGER.info("------->扣减账户开始account中");accountDao.decrease(userId,money);LOGGER.info("------->扣减账户结束account中");throw new RuntimeException("发生错误");}

(2)访问:http://localhost:8080/order/create?userId=1&productId=1&count=10&money=100,发现事务回滚

分布式事务框架seata介绍相关推荐

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

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

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

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

  3. 分布式事务——分布式事务简介、分布式事务框架 Seata(AT模式、Tcc模式、Tcc Vs AT)、分布式事务—MQ

    分布式事务--分布式事务简介.分布式事务框架 Seata(AT模式.Tcc模式.Tcc Vs AT).分布式事务--MQ 一.分布式事务简介 如果不是分布式环境的话一般不会接触到这种,一旦是微服务这种 ...

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

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

  5. 分布式事务框架Seata原理详解

    本文来深度解析下分布式事务框架Seata原理,知其然知其所以然. 文章目录 Seata概述 什么是2PC二阶段提交协议 MySQL XA方案 Seata核心知识 Seata设计目标 Seata组成结构 ...

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

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

  7. 分布式事务框架Seata

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

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

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

  9. 阿里分布式事务框架Seata

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

最新文章

  1. 快讯 | 第二届数据标准化及治理大会成功举办,清华力量助推中国数据标准化建设
  2. PAT乙级-1070. 结绳(25)
  3. Django 之 Cookie判断是否已登陆(写成类)
  4. 进程 zabbix_Zabbix监控在windows的进程(非进程数)
  5. 将SSM架构中原来关于springSecurity3.x版本的写法配迁移到SpringBoot2.0框架中出现的问题解决记...
  6. mybatis 配置_配置Mybatis在Spring Boot工程中的整合
  7. 《大企业云桌面运维实战》v1.13
  8. 音视频编解码技术(二):AAC 音频编码技术
  9. linux终端执行二进制文件命令,Linux下查看二进制文件命令
  10. AutoCAD.net 自定义窗体及面板与CAD交互时的焦点切换问题(C#)
  11. excel中自定义数据格式后,如何将其实际显示为自定义后的数据,不受原格式数据的限制
  12. WordPress外贸建站多语言翻译插件推荐
  13. 破解access密码
  14. 华为云服务部署Rstudio Server
  15. 信号的扩展是因果_信号与系统 怎么判断e(1-t)的时不变和因果性?
  16. JCMsuite应用:光学环形谐振腔模拟
  17. 培训机构到底好不好?学历重要吗?java
  18. 网易图灵学院python公开课_图灵学院 Python全系列教程全栈工程师 python视频教程下载...
  19. 软件测试 —— Python(一)之Python基础
  20. 【轴承故障分解】基于matlab ITD轴承故障信号分解【含Matlab源码 1871期】

热门文章

  1. apk 进行系统签名
  2. 海盗分赃问题-----简化问题,分而治之
  3. 百度地图实现自定义搜索
  4. Armeria 小试牛刀
  5. 通用课程表教师表php,利用Access实现学校课程表的科学管理
  6. Win11怎么打开AMD显卡控制面板
  7. SSM框架搭建与实战案例
  8. redis事务与持久化
  9. ps顶级调色技术解密视频教程 终极大法
  10. 基于ITIL的医院信息化服务管理实践(客户说)