八股的问题里Spring存在不足,无法将八股的知识和项目串联起来。
记录几个值得研究的问题:
-
端口80到8080是怎么到的 又是怎么一步一步到controller?
[用户请求80端口]
↓
[Nginx监听80端口并转发 → 8080]
↓
[Tomcat监听8080端口,解析请求]
↓
[DispatcherServlet拦截 → doDispatch()]
↓
[HandlerMapping匹配对应Controller方法]
↓
[HandlerAdapter执行方法]
↓
[返回数据 / 视图]
↓
[响应返回给用户]
Spring Boot 应用默认监听的是 8080端口,而用户常访问的 80端口 通常通过 Nginx反向代理 实现转发,将外部请求重定向至 Spring Boot 的端口;请求到达后,会由 内嵌Tomcat 解析为标准的 HttpServletRequest,交由 DispatcherServlet(前端控制器) 处理,通过 HandlerMapping 匹配对应的 Controller方法,再由 HandlerAdapter 执行方法并生成响应,最终返回给客户端,完成整个请求响应链路。 -
spring事务传播属性
Spring 事务传播属性(Propagation)定义了当前方法开启事务时,遇到已有事务该如何处理,共提供了 7 种类型,最常用的是前 3 种:-
REQUIRED(默认)
有事务就加入,没有就新建
最常见,用于大部分业务方法
✅ 例:下订单、扣库存、加积分应处于同一事务 -
REQUIRES_NEW
无论是否存在事务,都会新建一个事务
原事务挂起,适合需要独立提交/回滚的操作
✅ 例:操作日志写入,即使主事务失败也要保留日志 -
NESTED
嵌套事务,使用保存点回滚
属于当前事务的子事务,主事务异常会回滚全部
✅ 例:多个子模块操作,某个失败只回滚它自己,但主事务失败则全部回滚 -
其他不常用:
传播属性 说明
SUPPORTS 有事务就加入,没有就非事务执行
NOT_SUPPORTED 不使用事务,存在事务则挂起
NEVER 不能有事务,有事务则抛异常
MANDATORY 必须存在事务,没有事务则抛异常
总结一句话:
Spring 提供多种事务传播行为,以支持不同业务的事务隔离控制,常用的 REQUIRED 和 REQUIRES_NEW 能应对主事务 + 子事务、主事务失败子事务保留等典型业务需求。 -
-
哪些场景下 会导致事务注解失效
事务注解(@Transactional)常见失效场景主要有以下几类,简明总结如下:✅ 1. 方法不是 public
@Transactional 只能作用在 public 方法上;
非 public 方法不会被 Spring AOP 拦截,自然不会开启事务。✅ 2. 方法内部调用自身方法
Spring 的事务是通过代理实现的;
类内部方法直接调用不会走代理,事务不会生效。
❌ this.insertAndUpdate();
✅ 应通过代理调用,如 AopContext.currentProxy() 或拆分成不同 Bean。✅ 3. 注解加在接口或父类方法上
Spring AOP 默认是基于类(CGLIB),接口上的注解不会生效;
建议注解加在实现类的具体 public 方法上。✅ 4. 异常未被正确抛出
Spring 只在 运行时异常(RuntimeException)或 Error 才回滚事务;
如果捕获异常或抛出的是 CheckedException(如 IOException),事务不会回滚,除非手动指定 rollbackFor。
@Transactional(rollbackFor = Exception.class)✅ 5. 数据库本身不支持事务
比如使用的是 MyISAM 引擎,或者 Redis/Mongo 等非事务型存储。✅ 6. 多线程/异步调用
事务与线程绑定,异步线程中的操作不受主事务控制;
如需事务控制,异步任务需手动开启事务或使用 @Transactional 包裹其逻辑。一句话总结:
事务注解失效通常是因为 没走代理机制 或 异常未触发回滚条件,实际开发中要确保方法访问修饰符、调用方式、异常处理等都符合 Spring 的 AOP 事务要求。 -
表里有abc联合索引 sql a= b》 c= 这种场景下有索引失效为什么还会加这三个索引
一、联合索引结构回顾
假设有联合索引 (a, b, c),它实际是按照字典序构建的 B+ 树复合索引,遵循:
最左前缀原则:必须从最左字段开始连续匹配。二、SQL 示例分析
WHERE a = ? AND b > ? AND c = ?
a = ? ✅ 命中索引第一列;
b > ? ✅ 仍在联合索引中,但范围查询;
范围查询之后的字段(c)无法再用索引,c 索引失效。
⚠️ 注意:“索引失效”并不是说整个联合索引失效,而是c 列不能再用上该索引做快速定位,只能回表判断。三、那为什么还建 (a, b, c) 联合索引?
虽然部分字段失效,但仍然有价值:
✅ 1. 覆盖更多查询场景
(a, b), (a), (a, b, c) 全部能用;
提高命中范围,比三个单列索引更高效。
✅ 2. 提供最优查询路径
即使 c 失效,a+b 部分索引依旧可用,依然能显著减少扫描行数。
✅ 3. 利用覆盖索引
如果 SELECT 的字段正好是 (a, b, c),即使 c 不能用于过滤,也能避免回表,提高效率。四、总结一句话
虽然 b > ? 导致 c 无法再参与索引过滤,但联合索引 (a, b, c) 在多数场景下仍能提供索引前缀匹配加速 + 覆盖索引优化,比多个单列索引性能更好,是查询优化的重要手段。