事务特性
- 原子性:把数据库操作当一次操作,要么都成功,要么都失败
- 一致性:事务未完成之前后,所有操作线程锁能操作的数据是一样的
- 隔离性:多个事务之间的操作是互相不干扰
- 持久性:永久存储
事务的分类
- 本地事务:一个数据库就是一个本地事务
- 分布式事务:同时操作多个本地事务时,就是分布式事务的场景
CAP理论【死记】
分布式系统只能同时满足2个指标,但分区容错性一定发生,所以分布式系统一般是AP或者CP系统,AP最常见。
- 分区容错 Partition tolerance:不可抗拒的因素一定会发生(必须考虑的)
- 网络抖动
- 光纤挖断
- 运营商断网
- 可用性 Availability:高可用,让系统7*24小时正常服务
- 一致性 Consistency:与事务的一致性一致
BASE理论【死记】
Base理论是对CAP理论的补充,对AP系统补充一致性的最低实现要求,对CP系统补充可用性的最低实现要求。
-
基本可用,是多CP系统的补充
- 响应时间上的损失:正常情况下的搜索引擎 0.5 秒即返回给用户结果,而基本可用的搜索引擎可以
在 1 秒作用返回结果。
- 功能上的损失:在一个电商网站上,正常情况下,用户可以顺利完成每一笔订单,但是到了大促期
间,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。
- 响应时间上的损失:正常情况下的搜索引擎 0.5 秒即返回给用户结果,而基本可用的搜索引擎可以
-
最终一致性,是对AP系统的补充
- 所以数据一致性是一定要保障的,但是时间要求上可用存在延迟或中间状态
分布式事务的解决方案【熟悉】
-
两阶段提交的方案(2PC)
- 一定要基于XA协议,实现,同步等待的过程
- 优点: 尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不能100%保证强
一致) - 缺点: 不适合高并发高性能场景,对性能影响较大。
-
TCC补偿机制
- 锁定资源Try
- 事务提交Confirm,只要都锁定成资源,则每个事务都立即提交
- 事务回滚Cancel
- 优点: 相比两阶段提交,可用性比较强
- 缺点: 数据的一致性要差一些,开发量大
-
消息最终一致性解决方案【精通】
- 把分布式事务,拆分成多个本地事务,并通过消息驱动每个本地事务执行,直到每个本地事务都执行成功为止。
- 优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。
- 缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。
什么是Seata(fescar)
业务层实际操作:
1.先写fescar模块:
2:在业务层服务导入fescar模块的依赖:
3.在业务层服务添加注解:
@GlobalTransactional(name = “order_add”)
4.运行fescar服务:
-
定义:分布式事务的框架
-
优点:
- 解决了单点问题
- 解决了同步阻塞问题
- 开箱即用
- 能灵活的支持不同的事务场景(XA的源支持可有可无)
-
原理:
-
FescarRestInterceptor 指定Feign拦截器,让微服务之间(feign)也能传递xid信息
-
FescarRMRequestFilter 接收自定义header中的xid信息
-
-
AT 模式
-
需要数据源支持XA协议,是2PC流程的改进实现,同时借鉴TCC的后两步思想来实现异步提速
-
第一步:立即提交本地事务
-
第二步:清理日志或回滚
-
-
Mybatis通过注解来映射属性和字段的案例
@Select("select * from tb_task where update_time<#{currentTime}")
@Results({@Result(column = "create_time",property = "createTime"),
@Result(column = "update_time",property = "updateTime"),
@Result(column = "delete_time",property = "deleteTime"),
@Result(column = "task_type",property = "taskType"),
@Result(column = "mq_exchange",property = "mqExchange"),
@Result(column = "mq_routingkey",property = "mqRoutingkey"),
@Result(column = "request_body",property = "requestBody"),
@Result(column = "status",property = "status"),
@Result(column = "errormsg",property = "errormsg")})
List<Task> findTaskLessThanCurrentTime(Date currentTime);
消息最终一致性的实现方案【精通】
erty = “status”),
@Result(column = “errormsg”,property = “errormsg”)})
List findTaskLessThanCurrentTime(Date currentTime);
### 消息最终一致性的实现方案【精通】
![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pZSUjoAa-1593172648579)(%E7%AC%94%E8%AE%B0.assets/image-20200623173126751.png)\]](https://img-blog.csdnimg.cn/20200626200058100.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMjM2OTM1,size_16,color_FFFFFF,t_70)