事务就是保证数据库交易可靠性的一种机制
事务的四种特性
A 原子性: 事务操作要么全部成功,要么全部失败
C 一致性: 一个事务在执行前后数据库的状态都必须一致
I 隔离型: 事务相互隔离,不能被干扰
D 持久性:对数据库的操作成功以后,永久有效
因为事务无法满足分布式下的数据一致性,所以出现了分布式事务
分布式事务就是为了解决多数据库下实现数据一致性
首先我们要知道CAP定理 CAP定理也是三者不可兼得
C 一致性 在分布式系统中数据必须都是同一样的值
A 可用性 在集群中一部分节点故障后是否还可以相应客户端
P 分区容错性 区间通信可能会失败
一般来说,分区容错无法避免,所以认为P一定成立,所以要么AP,要么CP
seata是一个alibaba开发出得分布式事务解决方法,支持了AT,TCC,SAGA,XA事务模式
详细信息请移步官网自行了解.
我使用是使用了AT强一致性二阶段提交的事务模式
**使用seata请先下载服务端 我自己使用的是1.3.0 注册中心是nacos1.3.1
nacos下载
修改配置文件application.properties把注释掉的这个打开修改成对应的用户密码
然后把conf下的nacos-mysql.sql文件在mysql中执行 修改成对应的数据库名
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root
然后单机启动 ./startup.sh -m standalone
访问 localhost:8848/nacos就可以看到nacos启动成功
seata下载
在1.0.0以后一些配置文件都不在下载的包里,要自行下载
nacos-config.sh和config.txt下载
config.txt进去就可以看到,.sh文件下级目录可以找到
.sh下载过放到conf下,config.txt放到conf同级的目录
然后修改txt文件,将.sh执行,把配置加载到nacos中,启动时要加上端口号
在nacos中就可以看到加载了进来
修改配置文件的数据库配置,然后这里的组要跟client中的组对应,先记下来
seata需要的数据库表下载
undo_log下载
要在需要的每个数据库都添加undo_log表
修改file.conf和registry.conf文件
改成db,修改数据库信息
把注册中心修改nacos
下边的配置使用file文件就可以
以db方式启动
在bin目录下启动seata-server.sh -m db
可以看到seata注册到了nacos
最后文件是这样子的
//springboot包
org.springframework.boot
spring-boot-dependencies
2.2.6.RELEASE
pom
import
//springcloud包
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR7
pom
import
//alibabacloud包
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.1.RELEASE
pom
import
//seata包
io.seata
seata-spring-boot-starter
1.3.0
io.seata
seata-all
1.3.0
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
2.2.1.RELEASE
io.seata
seata-spring-boot-starter
//nacos注册中心
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
yml配置文件:
seata:
enabled: true
application-id: system-exporta //一般可以用服务名称 要唯一
tx-service-group: my_group //要和服务端的组对应
config:
type: nacos
nacos:
namespace:
server-addr: localhost:8848
group: SEATA_GROUP
username: nacos
password: nacos
registry:
type: nacos
nacos:
application: seata-server
server-addr: localhost:8848
group: SEATA_GROUP
namespace:
username: nacos
password: nacos
service:
vgroup-mapping:
my_group: default 和服务端的对应
在启动类上要把自动的数据源关闭,然后自己定义数据原
mybatis和mybatis-plus配置不同,千万别搞错
mybatis:
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
@Bean
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSourceProxy);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
bean.setMapperLocations(resolver.getResources(“你的xml文件位置”));
return bean.getObject();
}
mybatis-plus:
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
@Bean
@Primary
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSourceProxy);
bean.setTypeAliasesPackage("包路径"); //比如 com.xxx.xxx.mapper
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
bean.setConfiguration(configuration);
return bean.getObject();
}
**setTransactionFactory(new SpringManagedTransactionFactory())
这个配置是一个大坑,千万别加,找了一个星期为什么不回回滚
其余服务配置相同
然后使用就是在方法上加上一个
@GlobalTransactional(name = “save”,rollbackFor = Throwable.class)注解
被调用方不用加 加上注解就是一个TM,一个服务可以同时是一个TM和RM
name自己起,rollbackFor应该是接收到什么类型错误回滚
如果你在A服务的方法加了这个注解,然后调用了B服务,B服务报错的话是不会回滚的,必须要这个注解捕获到错误才可以回滚,可以在B方法抛出异常抛给A,这样就可以回滚**
启动一个服务:可以在服务端看到RM注册了进来
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
RM通俗一点可以说是事务参与者
TC就是事务协调者
TM可以算是事务发起者
只是自己理解
启动第二个服务
参与的两张表都是空数据
完成