MySQL 事务隔离级别

437 阅读3分钟

Hello,一周不见,这周过得好吗?

最近学习 MySQL 相关知识,刚好学习到了这个知识点,就整理出来和大家一起学习。

什么是事务

事务就是一组原子性的 SQL 查询,或者一个独立的工作单元。 --《高性能 MySQL》

这段话好像也比较抽象,通俗一点说,事务里面包含的 SQL 语句,要么全部执行成功,要么全部执行失败。比较经典的例子就是银行转账了,这个都烂大街了,不再重复叙述。

事务的四大特性(ACID)
  • 原子性(Atomicity)
    一个事务必须被视为一个不可分割的最小工作单元,整个事务中的操作要么全部成功,要么全部失败,不可能只执行其中一部分。

  • 一致性(Consistency)
    数据库总是从一个一致性的状态转换到另一个一致性的状态。以转账为例,A 转钱给 B,B 收到了这笔钱,不存在 A 转钱给 B,B 没有收到这笔钱这种情况。

  • 隔离性(Isolation)
    通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。还是以转账为例,A 转钱给 B,如果 B 没有收到这笔钱,事实上 A 就不会扣钱这笔钱。

  • 持久性(Durability)
    一旦事务提交,则其所做的修改就会永久保存到数据库中。

事务隔离级别
  • Read uncommitted(未提交读)
    事务中的修改,即使没有提交,对其他事务也都是可以见的。事务可以读取未提交的数据,这也被称为脏读。这个级别会有一堆问题,基本不会在实战中使用。

  • Read committed(提交读)
    一个事务开始的时候,只能“看见”已经提交的事务所做的修改。即一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。有些时候也成为不可重复读,因为执行两次同样的查询,可能会得到不一样的结果。这是大多数的数据库默认的隔离级别。

  • Repeatable read(可重复读)
    该级别保证了在同一个事务中多次读取同样的记录结果是一致的,解决了脏读问题,但存在幻读问题。这是 MySQL 的默认隔离级别。

  • Serializable(可串行化)
    这是数据库最高的隔离级别,通过强制事务串行执行,避免了幻读的问题。简单来说,Serializable 会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题,实际应用中很少使用这个隔离级别。

用一张表格汇总。

隔离级别 脏读 不可重复读 幻读
Read uncommitted
(未提交读)
Yes Yes Yes
Read committed
(提交读)
No Yes Yes
Repeatable read
(可重复读)
No No Yes
Serializable
(可串行化)
No No No
总结

都是并发惹的祸,单线程就没有这么多事情。


欢迎关注公众号:卡戎,分享 Java 知识,大家一起共同进步。