AT模式下,客户端只需要关注自身的业务SQL,Seata框架会自动生成事务的二阶段提交和回滚操作。Seata-AT模式官网
AT模式遵循之前介绍2PC协议,分两个阶段进行分布式事务的管理
commit时序图

rollback时序图

引入pom依赖
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-seataartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.17version>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.2version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
application.properties文件
server:
port: 8001
spring:
application:
name: seata-order
cloud:
cloud:
discovery:
server-addr: localhost:8848
alibaba:
seata:
# 事务分组:mygroup
tx-service-group: mygroup
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
management:
endpoints:
web:
exposure:
include: '*'
seata:
tx-service-group: mygroup # 事务组名称,要和服务端对应
service:
vgroup-mapping:
mygroup: default # key是事务组名称 value要和服务端的机房名称保持一致
CREATE TABLE `stock` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`count` int(11) DEFAULT NULL,
`money` int(255) DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `order` (
`product_id` int(11) NOT NULL,
`count` int(11) DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
undo_log日志表可以去官网->开发者指南->各事务模式->Seata AT 模式,网址为:
sql语句在页面底部
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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
TM(order8001)事务管理者Controller
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private FeignService feignService;
@GetMapping("create")
@GlobalTransactional
/**
* 访问次接口的所有请求,都会被Seata管理分布式事务,
* 也就是TM(开始事务的服务器)
*/
public String create(){
feignService.decrease();
orderService.create();
return "SUCCESS";
}
}
TM(order8001)Service
@FeignClient("seata-stock")
@Service
public interface FeignService {
@GetMapping("stock/decrease")
public String decrease();
}
@Service
public class OrderServiceImpl implements OrderService {
@Resource
private OrderMapper orderMapper;
@Override
public void create() {
orderMapper.create();
}
}
RM事务参与者(stock8002)的Controller
@RestController
@RequestMapping("stock")
public class StockController {
@Autowired
private StockService stockService;
@GetMapping("decrease")
public String decrease(){
stockService.decrease();
return "减少库存";
}
}
此时,参与者会在undo_log中记载镜像,一旦有一个参与者报错,会全部使用日志的信息回滚数据,使所有库的数据为事务开始前的样子。
XA协议是一个用于解决分布式领域问题的协议,描述了全局事务和分支事务之间的接口,利用数据库本身的ACID特点,使RPC环境下依然能够实现事务,现在的许多数据库,例如Mysql,Oracle都支持XA协议。


注意,这里的回滚是数据库直接回滚,RM只会开启一个事务,并且根据TM的通讯知道需不需要回滚事务,而不是利用日志中的信息重新开启一个事务回滚。
XA模式的痛点:如果其中一个RM突然挂掉了,那么TM一直处于阻塞状态,锁不能释放,那么这个全局事务会一直无法结束,这是XA模式的一个问题。

同一个事务ID代表该两个分支事务处于同一个全局事务中。


AT模式存在软状态,并且如果网络通信较差,软状态持续的时间会比较长,因此,有可能出现数据脏读,但是XA模式在全局事务Prepare以前都不会提交,因此不会存在脏读问题。
此外,AT模式支持的是最终一致性,而XA模式是强一致性的,不需要用任何日志来记录镜像,不存在中间状态。
优点:
缺点:
如果在全局事务没有提交的时候,某一个RM挂掉了, 就可能会导致阻塞死锁的问题。
Try-Confirm-Cancel模式,其中:
优点:
TCC完全不依赖数据库,能够实现跨数据局,跨应用资源管理,对不同的数据访问实现了院子操作,可以解决复杂场景下的分布式事务问题。
缺点:
TCC模式是一种侵入性强的业务模式,需要各个业务系统自行实现,设计相对比较复杂。


TCC和AT模式的区别在于,AT模式的日志是统一管理的,会生成镜像,不需要自定义接口,而TCC是倾入性的,需要自己定义try,confirm和cancle逻辑,根据业务的情况调用对应的接口。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。
是一种长事务的解决方案,业务中每个参与者都会提交本地事务,当出现一个参与者的失败案例则反向补偿前面的事务参与者。


Saga模式提供了异构系统的事务统一处理模型。所有的子业务都不再直接参与整体事务的处理(只负责本地事务的处理),而是全部交由了最终调用端来负责实现,而在进行总业务逻辑处理时,在某一个子业务出现问题时,则自动补偿全面已经成功的其他参与者,这样一阶段的正向服务调用和二阶段的服务补偿处理全部由总业务开发实现。

Saga模式是基于状态机引擎实现的,但是具体的我也不懂,用的时候可以去官网康康官方网站Saga模式使用文档