本文是基于 极客时间——MySQL 实战 45 讲 整理的学习笔记,持续更新。
关于事务
起初会疑惑,事务是可以单独开启,也就是通过 begin/start transaction
这类命令,显式的开启事务。
那我单独的执行一个 update 语句时,是不是就表示没有开启事务?
并不是的,在 Mysql 中,有一个 autocommit
的参数,它表示是否自动启用事务,默认是启用的,
当我们没有显式地使用 begin/start transaction
时,直接执行一个 update 语句,表示这个 update 语句本身就是一个事务,语句完成的时候会自动提交。
你可能会问,既然有了这个自动启用事务,那为什么还需要手动来启用事务呢?
这是因为为了保证原子性,开发时,常常会遇到某个逻辑里面可能含有多个 MDL 操作,我们可能希望,这些操作要么全部成功,要么全部失败,那么这个时候,就会选择手动开启事务,将这些操作放在一个事务里面。
所以,我们在执行的任何一个 MDL 语句,都是带有事务的,只是,这类事务通常是自动启用/提交的,对于客户端的使用者来说,其过程是无感知的。
另外还有几点需要注意:
begin/start transaction
命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。- 如果想要马上启动一个事务,那么可以使用
start transaction with consistent snapshot
关于死锁
其实对于小公司的业务而言,数据库不太容易发生死锁的,也就是说,只要没有开启了但未释放的事务,或者长事务未提交以及慢查询这些,基本上不会出现死锁的问题。
(一个慢查询会导致表锁,此时对这张表进行增删改查都会被锁住。)
toC 场景的系统大多要面对较高的 QPS,即使是小型/中型公司使用 MySQL,没有那么高的查询量,单表数据在百万量级也属常见。
对于小公司来说,DB 同时又是非常脆弱的一环,因为只要一个工程师不慎将不带索引的查询代码带上线,就会导致线上事故。