分布式事务解决方案-Seata
Seata
一、什么是Seata
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
使用seata的原因
在springboot单体架构中,我们只需要使用@Transactional即可开启事务,让事务进行回滚,但在分布式下是无法进行的,因为服务与服务之间无法感知对方是否出错,是否需要进行回滚,无法控制其他服务的事务回滚。
所以就是用到了Seata中间件,成功一起成功,失败一起失败。
二、工作流程
这是大致的流程图,详细的可以参考官方文档:Seata
三、使用Seata
参考文章
选择 seata 版本之前一定要查看 cloud alibaba 对应的版本,否则会出现很各种问题!
根据对应的版本安装对应的Seata
1.添加 undo_log 表
每一个要使用分布式事务的数据库都需要一个 UNDO_LOG 表。
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;
2.修改Seata配置文件
- 我们这里使用的是nacos作为注册中心,修改registry.conf配置文件,修改下面两个地方即可
\seata\conf.registry.conf
- 本地文件配置内容–这里没做修改使用默认
下面是transaction log store,选择持久化到哪里,我们这里就使用本地文件持久化
如果是选择其他的就配置对应的配置\seata\bin\file.conf
- 双击启动Seata服务:
\seata\bin\seata-server.bat
- 启动后可以访问nacos查看是否注册成功
3.导入依赖
- 可以再common功能模块导入此依赖,其他模块未引用时启动项目可能会发生报错,可以排除依赖解决报错
也可以在哪个模块使用,在哪个模块下引入,避免发生不必要的报错
com.alibaba.cloud
spring-cloud-alibaba-seata
2.2.0.RELEASE
4.代理数据源
因为seata需要对数据源进行代理,所以我们需要用seata来封装代理我们的数据源,每个模块都需要写入
@Configuration
public class MySeataConfig {
@Autowired
DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties){
HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if(StringUtils.hasText(dataSourceProperties.getName()))
{
dataSource.setPoolName(dataSourceProperties.getName());
}
return new DataSourceProxy(dataSource);
}
}
5.添加配置文件
每个要使用分布式事务的微服务服务中都要添加这两个文件
- file.conf
- registry.conf
将Seata的这两个文件复制到项目的resources文件下即可
vgroup_mapping
需要修改
举例:
在vgroup_mapping.
后面追加你的服务名legoumall-ware
再加-fescar-service-group
6.添加注解文件
给大事务添加全局注解:@GlobalTransactional
小事务记得也要添加:@Transactional
四、启动项目
报错一
Auto proxy of DataSource can't be enabled as you've created a DataSourceProxy bean.Please consider removing DataSourceProxy bean or disabling auto proxy of DataSource.
发现在seata1.2版本之后就不需要我们手动配置代理数据源了,所以就可以省略第4部
报错二
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy80 cannot be cast to com.zaxxer.hikari.HikariDataSource
更换一个数据源类型就可以解决启动项目
type: com.mysql.cj.jdbc.MysqlDataSource
五、结论
使用 Seata 来控制事务,它在执行过程中,首先有几大步,要获取全局锁、还有其它各种锁,要隔离都是要使用各种锁机制。
这样的话,做一个事务的时候,我们会发现它要加超多的锁,一加锁以后,相当于把并发变成串行化了。
这样的话,当系统高并发起来的时候,假设是订单系统,如果都这么做,所有人可能都得等待上一个订单下完,才能下下一个订单,这样整个系统就没法用了。
因为在分布式高并发的情况下,seata的XA模式、2PC 和TCC-事务补偿性方案方法性能欠佳,我们之后会考虑使用MQ的延时队列来完成事务
还没有评论,来说两句吧...