☰
Mysql进阶篇---触发器,锁
2026/10/15 6:17:50 网站建设 项目流程

触发器(⭐⭐)

一.介绍

二. 案例1(insert类型)

例子:

三.案例2(update类型)

四.案例3(delete类型)

总结:

触发器是:表发生增删改时,数据库自动执行一段逻辑。

  • 致命问题:逻辑隐形!代码层看不到这个逻辑,你在 Java 更新表,它偷偷在数据库里执行操作。排查 bug 极其痛苦,事务、死锁、数据异常很难定位。
  • 适用场景极少:历史数据归档、审计日志(极少数场景)。
  • 踩坑例子:更新 A 表,触发器改 B 表,B 表又有触发器改 A 表 → 循环触发,直接炸库。
  • 尽量不要写,老项目维护,新项目不新增。

锁(⭐⭐⭐⭐⭐)

一.介绍

二.全局锁

1.介绍

演示

2.一致性数据备份

创建全局锁后,只读,增删改会被阻塞:

全局锁释放掉后,可以增删改数据:

特点:

mysqldump --single-transaction 原理:

适用引擎:InnoDB,底层依靠MVCC实现,不锁表,业务可以正常读写,拿到一个统一时间点的一致性快照。

核心流程:

  1. 备份开始时,mysqldump 开启一个事务,隔离级别是REPEATABLE READ(RR)。
  2. 执行START TRANSACTION WITH CONSISTENT SNAPSHOT;这句话的作用:开启事务的瞬间,就创建 Read View 快照。
  3. 之后所有读表操作,全部基于这一份快照读取数据。
    • 别的线程新增、修改数据,不会影响当前备份会话读到的数据(undo log 版本链,多版本)
    • 不会加表锁,业务 DML 增删改可以正常执行,不会阻塞业务。
  4. 遍历所有表,把快照里的数据导出到 sql 文件。
  5. 事务结束,备份完成。

关键要点:

✅ 优点:无锁备份,不阻塞线上业务,拿到一致性备份

❌ 限制:

  1. 只支持 InnoDB;MyISAM 引擎没有事务和 MVCC,这个参数无效。
  2. 备份过程中,不能执行 DDL(alter、drop、truncate),如果备份中途别人改表结构,会破坏快照,直接报错,备份失败。
  3. 原理是快照读,不是冻结数据库。备份期间业务数据照常写入,只是备份读取旧版本数据。

三.表级锁

介绍:

1.表锁

(1)读锁

读锁不会阻塞其他客户端的读,但会阻塞其他客户端的写:

释放锁后,解除阻塞状态:

(2)写锁

设置锁的客户端又能读又能写,其他客户端读写都会阻塞:

释放锁后,解除阻塞状态:

2.元数据锁

两个客户端开始事务后,执行 select 和 update 语句,系统自动加上了 SHARED_READ 和 SHARED_WRITE 锁,这两个锁是兼容的:

提交事务后,重新启动一个事务,客户端1 执行 select 语句,客户端2 执行 alter table 语句来修改表结构,这时客户端2会阻塞,因为 EXCLUSIVE 锁和其他 MDL 互斥:

此时客户端1 提交事务,客户端2会解除阻塞状态,来修改表结构。

怎么验证是元数据锁起了作用呢?

很明显执行了对应的语句后,系统自动加上了相应的元数据锁:

3.意向锁

加表锁时会根据判断是否兼容意向锁来决定是否创建,兼容则创建表锁,不兼容则阻塞到事务提交

引入意向锁后,创建表锁只要判断是否兼容意向锁 而不用逐行检查行锁情况

测试:

IS:

IX:

四.行级锁

1.介绍

2.行锁

演示

1.

2.

此时客户端2 修改id为3的数据, 阻塞 , 原因是客户端1 根据name修改 但是name没有创建索引 ,行锁升级为表锁,给name创建索引后,就能解决:

3.间隙锁和临键锁

1.id为5的记录不存在 ,优化为间隙锁 ,锁住了3-8这个间隙,此时插入id=7的数据,阻塞

2.给age创建普通索引 ,查询age=3的数据 ,发现age=3这行数据被锁住,3之前的间隙和之后的间隙也被锁住

3.范围查询 id>=19的数据 19这一行数据被行锁锁住 一个临键锁锁住了25这一行,和前面的间隙,另一个临键锁 锁住了正无穷大和其到25之间的间隙

注意事项

五.总结

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询