分布式事务的相关知识-seata

分布式相关知识:

事务:原子性,一致性,隔离性,持久性。

不同的服务,操作不同的库

1:分布式事务CAP定理:

  • Consistency 一致性 :数据应该是完全一样的。集群越少越好!

  • Availability 可用性 :可用性讲的是同一份数据,有多份部署。集群越多越好!

  • Partition tolerance 分区容错 :多个数据库之前在同步数据的时候,有个时间差,这个时间范围就是容错范围。容错性必然存在。

2:BASE理论:

Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写

基本可用 - 说的是不要集群太多,可用就可以了。

软状态 - 本地事务,要么都成功,要么都失败。分布式事务允许部分成功。

最终一致性 - 最后的最后,要么都成功,要么都失败。

分布式解决方案:

3:两阶段提交

第一阶段:TM(事务管理器)收集RM(我们的微服务)事务信息,进行注册。

第二阶段:微服务操作数据库的时候,把操作的结果通知给TM,TM就返回是成功或失败。

4:TCC 其实就是采用的补偿机制

  • Try 阶段主要是做业务逻辑
  • Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
  • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

**5:消息最终一致性 **:

​ 主要业务一定要完成,次要业务可以通过别的方式最终完成。

​ 一般情况下,最终一致性要保障的是最终都成功!

6:Seata 解决分布式事务

​ 2019年1月份开源。非常适合解决微服务分布式事务 。性能高 。使用简单。

使用seata

1.开启数据库的 binlog日志

2.创建表(存储数据表的事务日志)

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`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3.下载软件

https://github.com/seata/seata/releases

修改conf下面的file.conf mode=" file "

seate集成到工程里面

1.导包

因为有多个工程都需要引入seata,所以新建一个工程seata的微服务模块来专门来处理分布式事务

<dependencies>
       
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <version>2.1.0.RELEASE</version>
            <!--排除-->
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>0.9.0</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
    </dependencies>
2: 创建代理数据源

(1)因为多个工程都需要依赖与seata,所以在seata模块下创建seata的配置类

package com.ding.seata.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import io.seata.rm.datasource.DataSourceProxy;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
@EnableConfigurationProperties({MybatisPlusProperties.class})
public class DataSourcesProxyConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }
    //创建代理数据源

    @Primary//@Primary标识必须配置在代码数据源上,否则本地事务失效
    @Bean
    public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }

    private MybatisPlusProperties properties;

    public DataSourcesProxyConfig(MybatisPlusProperties properties) {
        this.properties = properties;
    }

    //替换SqlSessionFactory的DataSource
    @Bean
    public MybatisSqlSessionFactoryBean sqlSessionFactory(DataSourceProxy dataSourceProxy, PaginationInterceptor paginationInterceptor) throws Exception {

        // 这里必须用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSourceProxy);
        mybatisSqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());

        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/mapper/*.xml"));

        MybatisConfiguration configuration = this.properties.getConfiguration();
        if(configuration == null){
            configuration = new MybatisConfiguration();
        }
        mybatisSqlSessionFactoryBean.setConfiguration(configuration);

        //设置分页
        Interceptor[] plugins = {paginationInterceptor};
        mybatisSqlSessionFactoryBean.setPlugins(plugins);


        return mybatisSqlSessionFactoryBean;
    }
}

(2)分别在 需要进行分布式事务控制的模块 引入 seata工程的坐标 ,并且添加一下配置类 config :

@Configuration
@ComponentScan(“com.ding.seata.config”)
public class SeataConfig {

}

3 配置seata-server链接和注册中心信息

3.1配置

将配置文件file.conf和配置文件register.conf 放到 每个需要参与分布式事务项目的resources中

修改文件file.conf :vgroup_mapping. " 模块名 " _tx_group = “default”

把user_tx_group换成本项目的名称就可以了。

3.2.修改application.yml

spring:
  cloud:
    alibaba:
      seata:
        tx-service-group: 模块名_tx_group
4:(最重要的是)要在业务方法上添加注解:
添加注解 @GlobalTransactional
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值