Boo's Blog

Stay foolish, Stay hungry

本文是基于 极客时间——MySQL 实战 45 讲 整理的学习笔记,持续更新。

关于事务

起初会疑惑,事务是可以单独开启,也就是通过 begin/start transaction 这类命令,显式的开启事务。

那我单独的执行一个 update 语句时,是不是就表示没有开启事务?

并不是的,在 Mysql 中,有一个 autocommit 的参数,它表示是否自动启用事务,默认是启用的,

当我们没有显式地使用 begin/start transaction 时,直接执行一个 update 语句,表示这个 update 语句本身就是一个事务,语句完成的时候会自动提交。

你可能会问,既然有了这个自动启用事务,那为什么还需要手动来启用事务呢?

这是因为为了保证原子性,开发时,常常会遇到某个逻辑里面可能含有多个 MDL 操作,我们可能希望,这些操作要么全部成功,要么全部失败,那么这个时候,就会选择手动开启事务,将这些操作放在一个事务里面。

所以,我们在执行的任何一个 MDL 语句,都是带有事务的,只是,这类事务通常是自动启用/提交的,对于客户端的使用者来说,其过程是无感知的。

另外还有几点需要注意:

  1. begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。
  2. 如果想要马上启动一个事务,那么可以使用 start transaction with consistent snapshot

关于死锁

其实对于小公司的业务而言,数据库不太容易发生死锁的,也就是说,只要没有开启了但未释放的事务,或者长事务未提交以及慢查询这些,基本上不会出现死锁的问题。

(一个慢查询会导致表锁,此时对这张表进行增删改查都会被锁住。)

toC 场景的系统大多要面对较高的 QPS,即使是小型/中型公司使用 MySQL,没有那么高的查询量,单表数据在百万量级也属常见。

对于小公司来说,DB 同时又是非常脆弱的一环,因为只要一个工程师不慎将不带索引的查询代码带上线,就会导致线上事故。

评论