3. 事务失效的情况
Spring事务的失效的几种原因--在类和类的方法上使用@Transactional
a. 数据库引擎不支持事务
mysql的myISAM引擎不支持事务。需要改成InnoDB才可以
b. @Transactional所在类非spring容器的bean
如果在service中没有加@service注解,则这个类不会被加载成bean,也就不会被spring管理。事务也就自然失效。
c. 方法不是public
@Transactional只能用于public,否则事务会失效;即使方法是public的,但是如果被private方法调用,事务同样也会失效。
d. 数据源没有配置事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
e. 事务的propagation传播机制设置错误
Propagation.NOT_SUPPORTED 以非事务的方式执行,如果当前存在事务,就把当前事务挂起
f. Catch语句没有抛出异常
把异常吃了,然后又不抛出来,事务也不会回滚
g. 抛出异常类型错误
@Transactional 默认回滚的是RuntimeException 和error,而Exception是RuntimeException 的父类,事务不会生效
如果想触发其他异常的回滚,需要在注解上配置一下,如@Transactional (rollbackFor = Exception.class )
h. 确保业务和事务入口在同一个线程
该注解方法中如果又起线程,则业务事务不生效
i. 自身调用的问题
@Transactional的事务开启,或者是基于接口的或者基于类的代理被创建。所以在同一个类中一个无事务的方法调用另一个有事务的方法,事务是不会起作用的----类的内部方法调用是不起作用的
4.数据库的索引失效的情况
以复合索引name 和age 为例
- 全职匹配 name = zhangsan and age = 18
- 最佳左前缀法则,带头大哥不能死,中间兄弟不能少 where age = 18
- 不要再索引列上做任何操作 where left(name,1) = zhang and age =18
- 范围条件后列上索引失效,where age>1 and name =zhangsan
- 尽量使用覆盖索引,减少使用select *
- 使用不等于 <, >,!= 索引会失效
- 使用is null或者is not null也不能使用索引
- Like 已通配符开头(%abc) 导致索引失效。解决方法,使用覆盖索引
Select * from student where name like ‘%zhangsan%’失效
Select name from student where name like ‘%zhangsan%’有效
9. 少用or ,用它来链接索引会失效 where name = ‘zhangsan’or age =18
5. 单服务到微服务的拆分
单体服务架构的优势
1易于开发 2易于测试 3 易于部署
单体架构的不足
1复杂性高 2交付效率低3伸缩性差只能按整体横向扩展,无法分模块垂直扩展,IO密集型模块和CPU密集型模块无法独立升级和扩容 4可靠性差,一个bug可能影响整个项目的运行 5 阻碍技术创新
微服务架构的优势
1易于开发和维护 2 独立部署 3 伸缩性强 4 与组织结构想匹配 5 技术异构性
微服务面临的挑战
1 服务拆分
拆分原则:领域模型,组织结构,康威定律,单一职责
微服务拥有独立数据库
微服务之间确定服务边界
2 数据一致性
可靠性事件模式
补偿模式-sagas模式
3 服务通信
通信技术方案:RPC REST 异步消息
服务注册与发现
负载均衡
4 服务网关
API Gateway
为前端服务的后端
身份认证,路由服务,流量控制,日志统计
5 高可观察
健康检测,集中控制
日志聚合检索
分布式追踪
6 可靠性(客户端实现)
流量控制,超时监控
舱壁隔离(线程隔离),熔断机制
服务降级,幂等重试
拆分原则
a 单一原则,高内聚低耦合 b 服务粒度适中 c 考虑团队结构 d 已业务模型切入 e 演进史拆分 f 避免环形依赖和双向依赖 g DDD
拆分步骤
a 分析业务模型 弱耦合在一起,高内聚力 b 确定服务边界 服务应包含单一的界限上下文 c 微服务数据库拆分
微服务的数据一致性
1 分布式事务不适用微服务 2PC会有单点故障 由于锁的原因降低吞吐量 NoSQL数据库并不支持
2 采用最终一致性,来实现数据一致性 可靠性时间模型:消息队列(支付宝转余额宝) 补偿模式-sagas 一些列的有序事务(每个事务也都有一个补偿子事务)
6. 注册中心-zookeeper-eureka-consul
组件名 语言 CAP 服务健康检查 对外暴露接口 springCloud
Eureka Java AP 可配支持 HTTP 已集成
Consul GO CP 支持 HTTP/DNS 已集成
Zookeeper Java CP 支持 客户端 已集成
AP:满足可用性,分区容错性的系统,通常对一致性的要求低一些
CP:满足一致性,分区容错性的系统,通常性能不是特别高
CA:单点集群,满足一致性,可用性的系统,通常扩展性上不太强大
7. 微服务的数据一致性
ACID数据库事务正确执行的四个基本要素
原子性A:要么全部完成,要么全部不完成,不存在中间状态
一致性 C:事务必须保持系统处于一致的状态
隔离性 I:事务之间相互隔离,同一时间仅有一个请求用于同一数据
持久性D : 事务一旦提交,该事务对数据库所做的更改持久的保存在数据库之中,并不会被回滚
电商为例,支付,订单,积分功能抽成三个服务,每个服务都有独立的数据库做数据存储。无论是修改订单状态失败,还是增加积分失败,都会导致数据的不一致
支付---订单---积分
为了解决这种问题,最后的方法避免微服务,实现本地事务保证数据的强一致性。但微服务架构中,每个服务都有自己的数据库,导致微服务系统不能简单的满足本地事务的特性
8. JWT (json web token)
基于token的进行身份认证的方案
Jwt设计一个字符串由header,payload,signature组成
Jwt头 +有效载荷+签名
具备安全,自包含,紧凑等特点
优点:
安全性高,防止token被伪造和篡改
自包含,减少存储开销
跨语言,支持多种语言的实现
支持过期,发布者校验
注意:
消息体可以被base64解密成铭文
Jwt不适合存放大量信息
无法作废未过期的jwt (可以借用Redis实现)
9. 分布式系统的CAP理论和BASE理论
C:一致性,所有数据变动都是同步的
A:可用性,即在可以接受的时间范围内正确的相应客户的请求
P:分区容错性,即某节点或网络出现故障时,系统扔能提供满足一致性和可用性的服务
关系型数据库,单节点,保证了数据强一致性C和可用性A,但是却无法保证分区容错性P
然而在分布式系统下,为了保证模块的分区容错性P,只能在数据强一致性C和可用性A之间做平衡。具体表现为在一定时间内,可能模块之间数据是不一致的,但是通过自动或手动补偿后能够达到最终的一致。
BASE理论
BA:基本可用
S:软状态,状态可以有一段时间不同步
E:最后一致,最终数据是一致的就可以了
BASE理论主要是通过牺牲强一直性来保证系统的可用性
可靠消息最终一致性
可靠消息最终一致性方案本质上是利用MQ组件实现的二阶段提交。此方案涉及3个模块
上游应用,执行业务并发送MQ消息
可靠消息服务和MQ消息组件,协调上下游消息的传递,并保证上下游数据的一致性
下游应用,监听MQ的消息并执行自身业务