本地事务&&分布式事务浅谈

一、本地事务

1.1 事务的基本性质:

原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)、持久性(Durabilily),简称就是 ACID

1) 原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败

2) 一致性:数据在事务的前后,业务整体一致。

eg: 转账。A:1000;B:1000; 转 200 事务成功; A:800 B:1200

3) 隔离性:事务之间互相隔离。

4) 持久性:一旦事务成功,数据一定会落盘在数据库。

1.2 事务的隔离级别:

1) READ UNCOMMITTED(读未提交) 该隔离级别的事务会读到其它未提交事务的数据,此现象也称之为脏读。

2) READ COMMITTED(读提交) 一个事务可以读取另一个已提交的事务,多次读取会造成不一样的结果,此现象称为不可重 复读问题,Oracle 和 SQL Server 的默认隔离级别。

3) REPEATABLE READ(可重复读) 该隔离级别是 MySQL 默认的隔离级别,在同一个事务里,select 的结果是事务开始时时间 点的状态,因此,同样的 select 操作读到的结果会是一致的,但是,会有幻读现象。MySQL 的 InnoDB 引擎可以通过 next-key locks 机制(参考下文"行锁的算法"一节)来避免幻读。

4) SERIALIZABLE(序列化) 在该隔离级别下事务都是串行顺序执行的,MySQL数据库的 InnoDB 引擎会给读操作隐式 加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。

可通过@Transactional(isolation = Isolation.REPEATABLE_READ) 进行设置。

1.3 事务的隔离级别:

1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务, 就加入该事务,该设置是最常用的设置。

2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当 前不存在事务,就以非事务执行。

3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果 当前不存在事务,就抛出异常。

4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。 5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当 前事务挂起。

6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务, 则执行与 PROPAGATION_REQUIRED 类似的操作。

举个栗子

非springboot的本地事务

 1.4  SpringBoot 事务:

1).事务的自动配置

TransactionAutoConfiguration

2).事务的坑。。。。坑:

 快快快。。。知识点

现象:在同一个类里面,编写两个方法,内部调用的时候,会导致事务设置失效。

原因事务是使用代理对象来控制的。同一对象内,事务方法互调,默认失效;原因绕过了代理对象

解决

0)、导入 spring-boot-starter-aop

1)、@EnableTransactionManagement(proxyTargetClass = true)

2)、@EnableAspectJAutoProxy(exposeProxy=true)

3)、AopContext.currentProxy() 调用方法

二、分布式事务

1).CAP 定理

CAP 原则又称 CAP 定理,指的是在一个分布式系统中

1) 一致性(Consistency): 在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

2) 可用性(Availability) 在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)

3) 分区容错性(Partition tolerance) 大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。 分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。

CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。 一般来说,分区容错是无法避免的,因此可以认为CAP的p 总是成立的,那么CAP定理告诉我们,剩下的C、A是无法同时满足的

2).面对现实吧

        对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所 以节点故障、网络故障是常态,而且要保证服务可用性达到 99.99999%(N 个 9),即保证 P 和 A,舍弃 C。

是对 CAP 理论的延伸,思想是即使无法做到强一致性(CAP 的一致性就是强一致性),但可 以采用适当的采取弱一致性,即最终一致性。

BASE 理论:

1)基本可用(Basically Available)2)软状态( Soft State)3) 最终一致性( Eventual Consistency)

3)分布式事务几种方案:

1).2PC 模式、3PC:

2).柔性事务-TCC 事务补偿型方案  

 3).柔性事务-最大努力通知型方案

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

实现:业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只 记录消息数据,而不是真正的发送。业务处理服务在业务事务提交之后,向实时消息服务确 认发送。只有在得到确认发送指令后,实时消息服务才会真正发送。

防止消息丢失:

1、做好消息确认机制(pulisher,consumer【手动 ack】)

2、每一个发送的消息都在数据库做好记录。定期将失败的消息再次发送一 遍

4)Raft原理:

分布式系统中实现一致性的 raft 算法、paxos

节点状态:候选人、领导、随从

关键词: 自旋、心跳、选举

Raft

5)Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata 快速开始

5.1 SEATA 的分布式交易解决方案

5.2 使用

* Seata控制分布式事务
* 1)、每一个微服务先必须创建undo_logo;
* 2)、安装事务协调器;seata-server: https://github.com/seata/seata/releases
* 3)、整合
*      1、导入依赖  spring-cloud-starter-alibaba-seata  seata-all-1.0.0.jar
*      2、解压并启动seata-server
*          registry.conf注册中心相关的配置,修改registry type=nacos
*          file.conf
*      3、所有想要用到分布式事务的微服务使用seata DatasourceProxy代理自己的数据源
*      4、每个微服务,都必须导入registry.conf、file.conf 到resources下 
*		修改order、ware的file.conf
*        vgroup_mapping.{application.name}-fescar-service-group = "default"
		如:
		vgroup_mapping.gulimall-order-fescar-service-group = “default”
		vgroup_mapping.gulimall-ware-fescar-service-group = “default”
		或者 配置文件配置
		#spring.cloud.alibaba.seata.tx-service-group=sss
*      5、启动测试
*      6、给分布式大事务的路口标注@GlobalTransactional
*      7、每一个远程的小事务用 @Transactional

1).创建 UNDO_LOG 表 -每个数据库都加

SEATA AT 模式需要 UNDO_LOG 表

– 注意此处0.3.0+ 增加唯一索引 ux_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;

5.3 seata弊端

高并发下,分布式事务不适合seata,@GlobalTransactional

高并发下,可使用:可靠消息 + 最终一致性方案(异步确保型)

为了保证高并发,远程服务自己回滚。

1、可以发消息给远程服务

2、远程服务自己也可以回滚(自动解锁模式),消息(延迟队列)

添加seata配置类 --把Seata作为数据库代理

例如order项目:

order中
@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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值