day20 分布式事务

1.提交订单在分布式下从带来的事物问题

image-20221203213757804

  • 订单保存成功后,扣库存失败,因为2个操作所在的库不同,导致无法回滚订单数据
  • 订单保存成功后,扣库存因为网络波动的原因,导致返回失败,实际上已经成功,导致库存被扣,订单数据回滚

2.本地事物

1.事物的基本特性

image-20221203214320939

image-20221203214334352

2.事物的隔离级别

  • 读未提交:一个事物可以读取另一个未提交的事物
  • 读已提交:一个事物可以读取另外一个已提交的事物,多次读取结果可能不一致
  • 可重复读:mysql默认隔离级别,在同一个事物中,读取到的结果一致,但可能有幻读现象
  • 序列化:事物按串行顺序执行,没有并发能力

3.事物的传播行为

image-20221203215433455

  • springboot使用事物的坑

    • b、c事物都失效,原因是:同一个对象内事物方法互调默认实效,饶过了代理对象/事物上使用对象来控制的,如果改成bSerive.b()事物就可以生效了

      image-20221203221103193

    image-20221203221908576

3.分布式事务

1.cap理论

image-20221203231023935

2.base理论

  • 在多数情况下一般都是选用AP,所以base理论上对cap理论的延伸,思想是即使无法做到强一致性,但可以采用适当的采取若一致性,既最终一致性。

image-20221204095208496

4.分布式下一致性的几种解决方案

1.2PC模式-强一致性(不建议)

image-20221204100110689

扫描二维码关注公众号,回复: 14697638 查看本文章

image-20221204100152086

image-20221204100212690

2.TCC事物补偿-最终一致性

image-20221204101034089

image-20221204101128462

3.最大努力通知型方案-最终一致性

image-20221204101823202

4.可靠消息+最终一致性方案(异步确保型)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEyyGdSf-1670250663039)(…/images/image-20221204102300349.png)]

5.seata

  • 实现原理架构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBVCsjHj-1670250663039)(…/images/image-20221204105504610.png)]

  • 我这里使用的是seata0.7版本

  • 导入依赖

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            </dependency>
    
  • 修改registry文件type=nacos

    image-20221205222913720

  • 导入文件到resouce目录下

    image-20221205222931345

  • 添加seata配置类

    @Configuration
    public class MySeaTaConfig {
          
          
    
        @Autowired
        private DataSourceProperties dataSourceProperties;
    
        /**
         * 使用seata代理自已的数据源
         *
         * @param dataSourceProperties
         * @return
         */
        @Bean
        @Primary
        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);
        }
    }
    
  • 加上注解

    @GlobalTransactional
    
  • seata0.7版本坑

    • 无法使用mp的批量添加

猜你喜欢

转载自blog.csdn.net/weixin_53060535/article/details/128194617