Seat分布式事务学习

Seat分布式事务学习数据库事务关注点:特性(ACID):原子性、一致性、隔离性、持久性; 问题:脏读、不可重复读、幻读; 隔离级别:读未提交、读已提交、可重复读、串行化;数据库事务的特性:数据库的事务特性(ACID):原子性:指事务是一个不

数据库事务关注点:

  • 特性(ACID):原子性、一致性、隔离性、持久性;
  • 问题:脏读、不可重复读、幻读;
  • 隔离级别:读未提交、读已提交、可重复读、串行化;

数据库事务的特性:

数据库的事务特性(ACID):

     原子性:指事务是一个不可分割的工作单位,事务包含的所有操作要么全部成功,要么全部失败;
        一致性:指事务前后,数据库从一个一致性状态变换到另一个一致性状态,比如A和B一共有2000,无论A和B怎么相互转账,他们的总金额都是2000;
        隔离性:当多个用户并发操作某一数据时,数据库为每个用户开启一个事务,多个并发事务执行相互隔离,不能被其他事务所影响;
        持久性:一个事务一旦提交了,那么数据库中对应数据会产生永久性的变换,即使数据库系统出现故障的情况下,数据也不会丢失;

数据库事务存在的问题:

脏读

一个事务读到另外一个事务还没有提交的数据,称之为脏读。

如果事务A在操作的过程中更新了某条数据V的值,然后事务B读取到了V被事务A修改后的值,这时事务A因为出现异常导致回滚了,数据V又还原为原先的值了,那么事务B刚刚读取到的值其实是不存在的。

不可重复读

一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。

不可重复读强调的是其他事务对数据进行了修改或者删除,如:事务A先读取了一条数据V,然后事务B将这条数据V进行了更新或者删除操作,并且成功提交了事务,这时事务A再次读取了这条数据V,发现前后2次读取的数据不一致

幻读

指一个事务前后2次查询,读取到的记录数不一致。

相比于不可重复读,它强调的是记录条数的不一致。事务A通过查询读取到了1条记录,接着事务B插入了一条新的数据,并提交了事务,然后事务A再次进行了查询,结果返回了2条记录;

数据库事务的隔离级别:

        根据上述现象,SQL定义了四个隔离级别,隔离级别从低到高分别为:读未提交、读已提交、可重复的、串行化。随着隔离级别的提高,数据库的性能逐渐降低。

Read Uncommitted: 读未提交

        未提交的写事务不允许其他事务进行修改,但允许其他事务读取该数据,因此会出现脏读、不可重复读的情况

Read Committed: 读已提交

  • 未提交的写事务不允许其他事务读取,所以不会出现脏读;
  • 读事务允许其他事务访问并修改该行数据,所以可能会出现不可重复读的情况;

Repeatable Read: 可重复度

  • 读事务允许其他的读事务对数据进行访问,但是禁止其他的写事务对数据进行操作,所以在事务期间数据不会改变,除非该事务自己修改了数据;
  • 允许其他事务进行新增操作,所以会出现幻读的情况;

Serializable:串行化

  • 事务隔离的最高级别,要求所有的事务只能一个接着一个的顺序执行,性能最低;
  • 可以避免脏读、不可重复读、幻读的出现;

分布式事务

        随着业务量不断的上涨,单台引用无法撑起整个项目服务的运行,这时候就涉及到分库分表。同时,会按照业务划分将业务拆分成多个单一项目部署在各个服务器上,每台业务服务连接各自的数据库,这个时候就涉及到了分布式数据一致性问题,需要使用的事务,但是单一事务是无法满足现有的情况,从而衍生到分布式事务。

此处基于SpringCloud+nacos+seata+openfeign进行编写的案例。

环境:

nacos:1.3.2

Seata:1.3.0

Spring.cloud.alibaba.version:2.1.2.RELEASE

注:seata官方从1.0版本后不再提供sql脚本,以及nacos推送配置脚本,需要从0.9.0的版本复制

 0.9.0下载地址  1.3.0下载地址

Seat分布式事务学习

复制到1.3.0版本中。

 执行db_store.sql脚本,数据库名为seata

Seat分布式事务学习

第一步:修改file.conf文件

Seat分布式事务学习

  注意使用mysql8.0及以上版本的需要更改:driverClassName ="com.mysql.cj.jdbc.Driver"

第二步:修改registry.conf文件

Seat分布式事务学习

修改type为nacos,此处是声明你使用的注册中心
application为seata启动后注册到nacos的服务名

 修改:nacos-conf.txt文件

Seat分布式事务学习

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.thread-factory.boss-thread-prefix=NettyBoss
transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
transport.thread-factory.share-boss-worker=false
transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
transport.thread-factory.client-selector-thread-size=1
transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
transport.thread-factory.boss-thread-size=1
transport.thread-factory.worker-thread-size=8
transport.shutdown.wait=3
service.vgroupMapping.seata_tx_group=default
service.enableDegrade=false
service.disable=false
service.max.commit.retry.timeout=-1
service.max.rollback.retry.timeout=-1
client.async.commit.buffer.limit=10000
client.lock.retry.internal=10
client.lock.retry.times=30
client.lock.retry.policy.branch-rollback-on-conflict=true
client.table.meta.check.enable=true
client.report.retry.count=5
client.tm.commit.retry.count=1
client.tm.rollback.retry.count=1
store.mode=db
store.file.dir=file_store/data
store.file.max-branch-session-size=16384
store.file.max-global-session-size=512
store.file.file-write-buffer-cache-size=16384
store.file.flush-disk-mode=async
store.file.session.reload.read_size=100
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://192.168.56.10:3306/seata?useUnicode=true
store.db.user=root
store.db.password=root
store.db.min-conn=1
store.db.max-conn=3
store.db.global.table=global_table
store.db.branch.table=branch_table
store.db.query-limit=100
store.db.lock-table=lock_table
recovery.committing-retry-period=1000
recovery.asyn-committing-retry-period=1000
recovery.rollbacking-retry-period=1000
recovery.timeout-retry-period=1000
transaction.undo.data.validation=true
transaction.undo.log.serialization=jackson
transaction.undo.log.save.days=7
transaction.undo.log.delete.period=86400000
transaction.undo.log.table=undo_log
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registry-type=compact
metrics.exporter-list=prometheus
metrics.exporter-prometheus-port=9898
support.spring.datasource.autoproxy=false

 启动nacos后执行 :

sh nacos-config.sh 127.0.0.1

Seat分布式事务学习

执行完成后在nacos控制台可以看到。

Seat分布式事务学习

 启动seata

Seat分布式事务学习

 控制台

 Seat分布式事务学习

 项目中引入seata后只需要在相应的业务层加上

@GlobalTransactional注解即可。

项目搭建:

Seat分布式事务学习

三个模块重点在Seata配置上:

Seat分布式事务学习

 代码

Seata学习:

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

AT模式:

  • 基于支持本地 ACID 事务的关系型数据库。
  • Java 应用,通过 JDBC 访问数据库。

在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) 。

流程步骤图:

Seat分布式事务学习

核心组件:

  • 事务协调器 TC

                维护全局和分支事务的状态,指示全局提交或者回滚。

  • 事务管理者 TM

                开启、提交或者回滚一个全局事务。

  • 资源管理者 RM

                管理执行分支事务的那些资源,向TC注册分支事务、上报分支事务状态、控制分支事务的提交或者回滚。

 流程:

  • TM 请求 TC,开始一个新的全局事务,TC 会为这个全局事务生成一个 XID。
  • XID 通过微服务的调用链传递到其他微服务。
  • RM 把本地事务作为这个XID的分支事务注册到TC。
  • TM 请求 TC 对这个 XID 进行提交或回滚。
  • TC 指挥这个 XID 下面的所有分支事务进行提交、回滚。

其分为两阶段提交:

第一阶段:

        主要针对于业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

一阶段本地事务提交前,需要确保先拿到 全局锁 。

拿不到 全局锁 ,不能提交本地事务。

拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

第二阶段:

  • 提交异步化,非常快速地完成。
  • 回滚通过一阶段的回滚日志进行反向补偿。

最好的学习资源就是官方文档,建议大家仔细研读官方文档和源码。

官方文档:传送门

今天的文章Seat分布式事务学习分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/63132.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注