关于事务的几点常识
本地事务
该类事务需要满足四大特性:ACID
(原子性、一致性、隔离性、持久性),仅限于对单一数据库资源的访问控制。
- 原子性(
Atomicity
):指事务作为整体来执行,要么全部执行,要么全部不执行。 - 一致性(
Consistency
):指事务应确保数据从一个一致的状态转变为另一个一致状态。 - 隔离性(
Isolation
):指多个事务并发时,一个事务的执行不应影响其它事务的执行。 - 持久性(
Durability
):指已提交的事务修改数据会被持久保存。
柔性事务
如果将实现了 ACID
的四大事务特性的事务成为刚性事务的话,那么基于 BASE
事务要素的事务则成为柔性事务。
BASE
是基本可用、柔性状态和最终一致性这三个特性的缩写。
- 基本可用(
Basically Available
):允许分布式事务参与方不一定要同时在线。 - 柔性状态(
Soft state
):则允许系统状态更新有一定的延时。 - 最终一致性(
Eventually consistent
):通常是通过消息传递的方式保证系统的 最终一致性。
在 ACID
事务中对隔离性的要求很高,在事务执行过程中,必须将所有的资源锁定。而柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面移至业务层面。通过放宽对 强一致性 的要求,来换取系统吞吐量的提升。
基于 XA
规范的两阶段提交
通过抽象出来的 AP
(应用程序)、TM
(事务管理器)、RM
(资源管理器) 的概念可以保证事务的 强一致性。其中 TM
和 RM
间采用 XA
的协议进行双向通信。
与传统的本地事务相比,XA
协议增加了 Prepare
阶段,数据库除了被动接受提交指令以外,还可以反向通知调用方事务是否可以被提交。
TM
可以收集所有分支事务的 Prepare
结果,最后进行原子的提交,保证事务的强一致性。
Alibaba Seata 简介
概述
Seata
是一款开源的分布式事务解决方案,提供高性能和简单易用的分布式事务服务,提供了 AT
、SAGA
和 XA
事务模式。
术语
TC
事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。TM
事务管理器:定义全局事务的范围,从开始全局事务 > 提交或回滚事务。RM
资源管理器:管理分支事务处理的资源,与TC
合作以注册分支事务和报告分支事务的状态,驱动分支事务提交或回滚。
接入 Seata 分布式事务
首先我们用到的是 Seata
的 AT
模式,该模式的特点就是对业务无入侵式,分二阶段提交。
-
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
-
二阶段:提交异步化,非常快速,回滚通过一阶段的回滚日志进行反向补偿。
启动 Seata Server
创建表
在项目数据库中添加事务所要用到的表:
CREATE TABLE IF NOT EXISTS `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'increment id',
`branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME NOT NULL COMMENT 'modify datetime',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
引入依赖
在 pom.xml
中引入 Seata
依赖:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
在 application.yml
文件中加入以下配置:
seata:
enabled: true
application-id: test #可自定义
tx-service-group: my_test_tx_group #可自定义
# enable-auto-data-source-proxy: true
# use-jdk-proxy: false
service:
vgroup-mapping:
my_test_tx_group: default
grouplist:
default: 127.0.0.1:8091
# disable-global-transaction: false
config:
type: file
file:
name: file.conf
registry:
type: file
相关注解
在事务发起者的接口上加入 @GlobalTransactional
注解即可。
文章作者:彭超
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 彭超 | Blog!