分布式事务介绍

分布式事务介绍:

    1.什么是事务?
        数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。如转账业务:一方扣款,一方增加金额。
        
    2.事务的四个特性?
        1.原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
        2.一致性(Consistency):指的是操作前后,总数据保持保持不变。(-100块与+100块)
        3.隔离性(Isolation)**:多个事务并发执行时,一个事务的执行不应影响其他事务的执行。张三取钱不会影响李四取钱。
        4.持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。在事务结束时,此操作将不可逆转。
    
    3.什么是分布式事务?
        简单讲,在分布式系统中进行的事务就是分布式事务。意思就是说,在分布式系统中,也要保证事务的四个特性。
        
    4.分布式事务的模型;
        单个服务,多个数据库,是分布式事务;
        多个应用,多个数据库也是分布式事务;
        多个应用,调用其他的应用,再加上多个数据库也是分布式事务(微服务中的典型模型);
        
    5.CAP理论?
        CAP 定理,又被叫作布鲁尔定理。
        C(Consistency):一致性:
            对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,
            那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
        A(Availability):可用性:
            非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。
        P(Partition tolerance):分区容错性:
            当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
            
        CAP理论认为,这三个条件只能同时满足其中两个,不能同时满足三个;
        网络无法 100% 可靠,分区其实是一个必然现象。
        如果我们选择了 CA 而放弃了 P,那么当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是 A 又不允许,所以分布式系统理论上
        不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
        所以一般认为P是永远存在的,必须满足;
        
        BASE理论:基于CAP理论,BASE理论认为系统基本可用,数据最终保持就可以了(允许数据可以短暂不一致)。
        
    6.分布式事务的解决方案:
        1.基于XA协议的两阶段提交:
            假设数据库1控制库存,数据库2控制积分,数据库3控制日志;TransactionManagement为统一事务管理器
            第一个阶段:
                数据库1执行库存扣减操作,但是不提交----->汇报操作成功与否给TransactionManagement
                数据库2执行积分增加操作,但是不提交----->汇报操作成功与否给TransactionManagement
                数据库3执行记录日志操作,但是不提交----->汇报操作成功与否给TransactionManagement
            第二个阶段:
                TransactionManagement确认以上三个操作都成功了,然后通知三个数据库进行提交操作;
                若是以上三个操作有一个失败了,则进行回滚操作;
                
            优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。
            缺点:牺牲了可用性,对性能影响较大,不适合高并发高性能场景,如果分布式系统跨接口调用,目前 .NET 界还没有实现方案。
            
        2.补偿事务(TCC)
            TCC 将事务提交分为 Try(method1) - Confirm(method2) - Cancel(method3) 3个操作。
            其和两阶段提交有点类似,Try为第一阶段,Confirm - Cancel为第二阶段,是一种应用层面侵入业务的两阶段提交。
            
            Try:在这个阶段,先对数据进行备份,然后执行业务,提交事务,通知事务管理器操作成功与否;
            Confirm:在这个阶段,事务管理器确认对各个数据库的操作是否有异常,无异常则confirm并更改干掉备份数据,有异常则进入cancel
            Cancel:若有数据库操作失败,则执行代码,将原先的备份数据还原;
            
            优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些

            缺点:缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,
            所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
            
    7.分布式事务的实现技术:Seata
        1.Seata介绍:
            Seata是阿里巴巴开源的一款分布式事务解决方案,它具有以下优点:
                对业务无侵入:不必要写很多的补偿事务的代码;
                高性能:减少分布式事务解决方案所带来的性能消耗
            Seata有两种模式:
                1.AT模式:自动模式,不需要写很多自定义的业务代码,推荐使用这种模式;
                2.TCc模式:手动模式,需要自定义业务代码;
                
            Seata工作原理:
                第1阶段:
                    通过代理数据源,逆向解析SQL,保留执行操作之前的数据和操作之后的数据,放到日志记录中,执行commit操作
                第2阶段:
                    事务管理器收到了所有的分支事务状态汇报,
                        发现没有问题,全局提交决定。协调器就异步通知所有相关的分支事务进行删除日志文件。
                        发现如果有问题,就进行全局回滚。异步通知所有相关的分支事务找到日志记录,将数据进行回滚。
                        
        2.Seata的使用:
            0.在每一个分布式事务涉及到数据库中添加undolog表:
                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=4 DEFAULT CHARSET=utf8;

            1.在各个微服务中加入Seata的起步依赖;
                 <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-seata</artifactId>
                </dependency>
                  <dependency>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </dependency>
                
            2.配置代理数据源:
                @Bean
                @ConfigurationProperties(prefix = "spring.datasource")
                public DataSource dataSource() {
                    DruidDataSource druidDataSource = new DruidDataSource();
                    return druidDataSource;
                }

                @Primary//主要标识.
                @Bean("dataSourceProxy")//代理数据源
                public DataSourceProxy dataSourceProxy(DataSource dataSource) {
                    return new DataSourceProxy(dataSource);
                }

                @Bean("jdbcTemplate")
                @ConditionalOnBean(DataSourceProxy.class)//spring容器中如果有该bean就进行注入
                public JdbcTemplate jdbcTemplate(DataSourceProxy dataSourceProxy) {
                    return new JdbcTemplate(dataSourceProxy);
                }
                
            3.配置客户端连接到TC的服务器的地址的配置
                file.conf
                regestry.conf
                application.properties

                https://seata.io/zh-cn/docs/user/configurations.html
                
            4.开启TC服务器
                TC就是一个服务器 seata-server ,解压启动bin下的bat脚本就可以了
            5.在最开始的全局事务中添加一个注解,用于开启全局事务
                @GlobalTransactional
                
                
                
                
                
                
        
            
            
            
                
                
    
原文地址:https://www.cnblogs.com/lyle-liu/p/12785468.html