提供网站建设收益分录全网营销推广有哪些平台
web/
2025/9/28 23:38:31/
文章来源:
提供网站建设收益分录,全网营销推广有哪些平台,中国私企建筑公司十大排名,wordpress dz论坛模板Seata AT 模式
上一节中我们提到AT模式是基于XA事务模型演变过来的#xff0c;所以他的整体机制也是一个改进版本的两阶段提交协议。 第一阶段#xff1a;业务数据和回滚日志记录在同一个本地事务中提交#xff0c;释放本地锁和链接资源第二阶段#xff1a;提交异步化所以他的整体机制也是一个改进版本的两阶段提交协议。 第一阶段业务数据和回滚日志记录在同一个本地事务中提交释放本地锁和链接资源第二阶段提交异步化非常快速完成。回滚通过第一阶段的回滚日志进行反向补偿 接下来会解析整个执行流程中每一个阶段的具体实现 原来。同时为了更好的理解AT模式的工作机制我们以产品表za_product来描述整个流程表结构如下
CREATE TABLE za_product (id bigint(20) NOT NULL AUTO_INCREMENT,product_code varchar(100) NOT NULL,name varchar(100) NOT NULL,count varchar(128) NOT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8;AT模式第一阶段
业务流程中执行库存扣减操作的数据库操作时候Seata会基于数据源代理对原执行的SQL进行解析代理的配置代码如下。
Beanpublic DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource){return new DataSourceProxy(druidDataSource);}然后将业务数据在更新前后保存到undo_log 日志表中利用本地事务的ACID特性把业务数据的更新和回滚日志写入同一个本地事务中进行提交完整的执行流程如图 日志表结构如下
-- 注意此处0.7.0 增加字段 context
CREATE TABLE undo_log (id bigint(20) NOT NULL AUTO_INCREMENT,branch_id bigint(20) NOT NULL,xid varchar(100) NOT NULL,context varchar(128) NOT NULL,rollback_info longblob NOT NULL,log_status int(11) NOT NULL,log_created datetime NOT NULL,log_modified datetime NOT NULL,PRIMARY KEY (id),UNIQUE KEY ux_undo_log (xid,branch_id)
) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8;假设AT分支事务的业务逻辑是如下SQl
update za_product set count count-1 where product_code GP202103221029如上则第一阶段的执行逻辑如下 通过DataSourceProxy对业务SQL进行解析得到SQl的类型UPDATE表za_product条件where product_code “GP202103221029”等相关信息查询修改之前的数据镜像根据解析得到条件信息生成查询语句定位数据
select id,product_code,count name from za_product where product_code GP202103221029如上SQl得到产品的对应库存数据1000执行业务SQL更新这条记录的count count-1查询修改之后的数据镜像根据镜像杰哥通过主键定位数据
select id,product_code,count name from za_product where id 1得到修改之后的镜像数据此时count 999插入回滚日志把前后镜像数据以及业务SQl相关的信息组成一条回滚日志记录插入undo_log表中可以在对应数据库的undo_log表中获得数据如下图 rollback_info字段是一个文件类型包含了回滚的数据beforeImage和afterImage使用官网数据如下所示
{branchId: 2034562134,undoItems: [{afterImage: {rows: [{fields: [{name: id,type: 4,value: 1}, {name: name,type: 12,value: GTS}, {name: since,type: 12,value: 2014}]}],tableName: product},beforeImage: {rows: [{fields: [{name: id,type: 4,value: 1}, {name: name,type: 12,value: TXC}, {name: since,type: 12,value: 2014}]}],tableName: product},sqlType: UPDATE}],xid: xid:xxx
}提交前向TC注册分支事务申请za_product表中主机值等于1 的记录的全局锁本地事务提交业务数据的更新和签名步骤中生成的undo_log一起提交将本地事务提交的结果上报给TC从AT的第一阶段实现原理看分支的本地事务可以在第一阶段提交完成后马上释放本地事务所定的资源这个是AT事务和XA最大的不同点XA事务的两阶段提交一般锁定资源后持续到第二阶段的提交或者回滚后才释放资源所以实际上 AT模式降低了锁定的范围 从而大幅度提升了分布式事务处理的效率之所以这样实现是因为Seata记录了回滚日志即使第二阶段发生异常只需要更具undo_log记录的数据进行回滚即可。
AT模式第二阶段
TC接受到所有事务分支的事务状态汇报后决定对全局事务进行提交或者回滚。
事务提交
如果决定是全局提交说明此事所有分支事务已经完成了提交只需要清理undo_log日志即可这也是和XA最大的不同点因为在第一阶段各个分支的本地事务就已经提交了所以这里并不需要TC来触发所有分支事务的提交如下图 如上图中事务提交流程 分支事务收到TC的提交请求后吧请求放入一个异步队列并马上返回提交成功的结果给TC从异步队列中执行分支提交请求批量删除对应的undo_log日志。 第一个步骤中TC并不需要同步知道分支事务的处理结果所以分支事务才会采用异步的方式来执行因为对于提交操作来说分支事务只需要清理undo_log中的日志即可而即使清理失败也不会对整个分布式事务产生任何影响。
事务回滚
整个全局事务链中任何一个事务分支执行失败全局事务都会进入事务回滚流程。此处回滚根据undo_log中记录的镜像数据进行补偿如回滚成功则数据的一致性得到保持。如下流程 所有分支事务接受到TC的事务回滚请求后分支事务参与者开启一个本地事务执行流程如下 通过XID和branch ID查找到相应的undo_log记录数据校验拿undo_log中afterImage镜像数据与当前业务表中数据镜像比较乐观锁如果不同说明数据被当前全局事务之外的动作修改了那么事务不会回滚。如果afterImage中数据和当前业务表中对应的数据相同则根据undo_log中的beforeImage镜像数据和业务SQL的相关信息生成回滚语句并执行
update za_product set count 1000 where id 1提交本地事务并把本地事务的执行结果即分支事务回滚的结果提交给TC。
关于事务隔离性保证
ACID在事务特种有一个隔离性指多个用户并发的访问数据库的时候数据库为每一个用户开启的事务不能被其他事务的操作所干扰多个并发事务之间要相互隔离。在AT模式中当多个全局事务操作同一张表的时候他的事务隔离的保证是基于全局锁来实现的那么我们针对读隔离写隔离进行说明
写隔离 写隔离是为了在多个全局事务针对同一个表的同一个字段进行更新操作的时候避免全局事务在没有被提交之前被其他全局事务修改。写隔离的主要实现是在第一阶段本地事务提交之前确保拿到了全局锁。如果拿不到全局锁则不能提交本地事务。并且获取全局锁的尝试会有一个范围控制如果超出范围将会放弃全局锁的获取并且回滚事务释放本地锁。 我们用实际案例解析假设两个全局事务tx1tx2分别对za_product表的count字段进行更新操作count原始值100. tx1先执行开启本地事务拿到本地锁数据库级别的锁更新count count-1 99。本地事务提交之前需要拿到该记录的全局锁然后提交本地事务并释放本地锁。 tx2后执行同样先开启本地事务拿到本地锁更新countcount-1 98。本地事务提交之前尝试获取该记录的全局锁全局锁由TC控制由于该全局锁已经被tx1获取所以tx2需要等待以重新获取全局锁。如果全局事务整体提交那么提交时序图如下 如果tx1在第二阶段执行全局回滚那么tx1需要重新获得该数据的本地锁让后根据undo_log进行事务回滚。此时如果tx2仍然在等待该激励的全局锁同时持有本地锁那么tx1 分支事务的回滚会失败。tx1分支事务回滚过程会一直重试直到tx2的全局锁获取超时放弃全局锁并回滚本地事务释放本地锁之后tx1的分支事务才会回滚成功。而在整个过程中全局锁在tx1 结束之前一直被tx1 持有所以不会发生脏写问题。全局事务回滚时序图如下 读隔离
我们在数据库学习中指定有4种隔离级别 Read Uncommitted读取为提交内容Read Committed读取已经提交内容Repeatable read可重复读Serializable可串行化 在数据库本地事务隔离级别为Read Committed或者以上时候Seata AT事务模式的默认全局隔离级别是Read Uncommitted在该隔离级别所有事务都可以看到其他未提交事务的执行结果产生脏读。这在最终一致性事务模型中是允许存在的并且在大部分分布式事务场景中可以接受脏读。在某些特定场景中要求事务隔离级别必须Read Committed目前Seata是通过SelectForUpdateExecutor执行器对SELECT FOR UPDATE语句进行代理的SELECT FOR UPDATE 语句在执行时候回申请全局锁。如果全局锁已经被其他分支事务持有则释放本地锁回滚SELECT FOR UPDATE 语句的本地执行并重试。在这个过程中查询请求会被“BLOCKING”直到全局锁被拿到也就是读取的相关数据已经提交时候才返回。 上一篇分布式事务框架seata
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83583.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!