事务(TRANSACTION)是一个不可分割的逻辑单元,包含了一组数据库操作命令,并且把所有的命令作为一个整体向系统提交,要么都执行、要么都不执行。
事务作为系统中必须考虑的问题,无论是在单体项目还是在分布式项目中都需要进行处理,而尤其在分布式微服务调用的情况下,事务的处理就变得复杂。
本篇博客介绍分布式事务产生的场景,阐述了CAP理论,分析了分布式事务的解决思路,初步介绍了Alibaba分布式事务组件Seata,给出了部署方法。
1.介绍分布式事务产生的场景,阐述了CAP理论;
2.分析了分布式事务的解决思路;
3.初步介绍了Alibaba分布式事务组件Seata,给出了部署方法。
分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:
在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成。例如电商中比较常见的下单付款案例
完成上面的操作需要访问三个不同的微服务和三个不同的数据库。
订单的创建、库存的扣减、扣减会员积分在每一个服务和数据库内是一个本地事务,可以保证ACID原则。
但是当我们把三件事情看做一个"业务",要满足保证“业务"的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象,此时ACID难以满足,就需要分布式系统下的事务管理。
解决分布式事务问题,需要一些分布式系统的基础知识作为理论指导。
1998年,加州大学的计算机科学家Eric Brewer提出,分布式系统有三个指标。
用户访问分布式系统中的任意节点,得到的数据必须一致。
比如现在包含两个节点,其中的初始数据是一致的。用户向节点1发起一个写操作,将其改为data1=2。
接下来,用户的读操作就会得到2。这就叫一致性。
问题是,用户有可能向节点2发起读操作,由于节点2的值没有发生变化,因此返回的是dta1=1。节点1和节点 2读操作的结果不一致,这就不满足一致性了。
为了让节点2也能变为2,就要在节点1写操作的时候,让节点1向节点2发送一条消息,要求节点2也改成data1=2。
这样的话,用户向节点2发起读操作,也能得到data1=2。因此要想保住一致性,就必须实现节点1到节点2的数据同步。
用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝
如图,有三个节点的集群,访问任何一个都可以及时得到响应:
当有部分节点因为网络故障或其它原因无法访问时,代表节点不可用,但其他可用节点可以继续提供服务。
Partition(分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。
Tolerance(容错):容错表示在集群出现分区时,整个系统也要持续对外提供服务。
在分布式系统中,系统间的网络不能100%保证健康,一定会有故障的时候,而服务又必须对外保证服务。因此分区容错性不可避免。
当节点接收到新的数据变更时,就会出现问题了:
如果此时要保证一致性,就必须等待网络恢复,完成数据同步后,整个集群才对外提供服务,服务处于阻塞状态,不可用。
如果此时要保证可用性,就不能等待网络恢复,那节点1、节点2与节点3之间就会出现数据不一致。
综上所述,无法同时做到一致性和可用性。系统设计时只能选择一个目标,在P一定会出现的情况下,A和C之间只能实现一个。这就是CAP定理。
CP: 强一致性,弱可用性,牺性部分机器的可用性,保证数据一致性,如zookeeper、es
AP: 强可用性,弱一致性,牺牲一致性,保证可用性,如Eureka
分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理,有两种解决思路:
但不管是哪一种模式,都需要在各个子系统事务之间互相通讯,协调事务状态,也就是需要一个事务协调者
这里的子系统事务,称为分支事务,如上图中的订单服务、库存服务都为一个子事务,有关联的各个分支事务组织在一起称为全局事务。
http://seata.io/zh-cn
Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。
1、Seata提供了四种不同的分布式事务解决方案:
无论哪种方案,都离不开事务协调者。
2、Seata事务管理中有三个重要的角色:
具体的执行流程如下:
http://seata.io/zh-cn/docs/download
创建数据库
用seata提供的MySQL脚本进行数据库表的创建
进行seata的配置,在1.4版本下主要修改下面两个文件
修改registry.conf文件,主要设置注册方式为nacos,配置nacos相关的地址,组名,用户名密码等,让seata注册到nacos中
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
# 第一步 把type="file"修改为nacos
# 第二步 除了nacos之外的注册配置都删除
# 第三步 修改nacos的配置
type = "nacos"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "119.3.162.127:8848" # http://119.3.162.127/
group = "DEV"
namespace = "my-tianju"
cluster = "default"
username = "naocsPet5620"
password = "nacos"
}
}
# 第四步,删除除fi1e以外的配置
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
file {
name = "file.conf"
}
}
修改file.conf文件,配置事务日志的存储方案,这里设置为MySQL数据库,需要设置url,用户名和密码登参数
## transaction log store, only used in seata-server
# 第一步修T改mode="file"为db
# 第二步删除除db以外的配置
# 第三步修改db的配置
store {
## store mode: file、db、redis
mode = "db"
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.cj.jdbc.Driver"
url: "jdbc:mysql://192.168.150.101:3306/seata?serverTimezone=GMT%2B8"
user = "root"
password = "123"
minConn = 5
maxConn = 100
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
在bin目录下有两个启动的脚步,bat格式为window下启动,sh格式为Linux中启动
window下启动的后台打印信息
seata注册在nacos中成功
访问seata前端页面
1.介绍分布式事务产生的场景,阐述了CAP理论;
2.分析了分布式事务的解决思路;
3.初步介绍了Alibaba分布式事务组件Seata,给出了部署方法。