人的知识就好比一个圆圈,圆圈里面是已知的,圆圈外面是未知的。你知道得越多,圆圈也就越大,你不知道的也就越多。

0%

MySQL 事务隔离

事务基本要素:ACID

  • 原子性(Atomicity)
    事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现以下两种状态之一:全部成功执行、全部不执行。任何一项操作失败都将导致整个事务失败,同时其他已经被执行的操作都将被撤销并回滚,只打所有的操作全部成功,整个事务才算是成功完成。

  • 一致性(Consistency)
    事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。也就是说,事务执行的结果必须是使数据库从一个一致性状态转变到另一个一致性状态,因此当数据库只包含成功事务提交的结果时,就能说数据库处于一致性状态。而如果数据库系统在运行过程中发生故障, 有些事务尚未完成就被迫中断,这些未完成的事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。

  • 隔离性(Isolation)
    事务的隔离性是指在并发环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。也就是说,不同的事务并发操纵相同的数据时,每个事务都有各自完整的数据空间,即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的 各个事务之间不能互相干扰。

  • 持久性(Durability)
    事务的持久性也被称为永久性,是指一个事务一旦提交,它对数据库中对应数据的状态变更就应该是永久性的。换句话说,一旦某个事务成功结束,那么它对数据库所做的更新就必须被永久保存下来——即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束时的状态。

脏读、幻读、不可重复读

  • 脏读
    指一个事务 A 正在访问数据,并且对该数据进行了修改,但是这种修改还没有提交到数据库中(也可能因为某些原因 Rollback了)。这时候另外一个事务 B 也访问这个数据,然后使用了这个被 A 修改的数据,那么这个数据就是脏的,并不是数据库中真实的数据。这就被称作脏读。

解决办法:把数据库事务隔离级别调整到 READ_COMMITTED。

  • 不可重复读
    指在一个事务 A 内,多次读同一个数据,但是事务 A 没有结束时,另外一个事务 B 也访问该同一数据。那么在事务 A 的两次读数据之间,由于事务 B 的修改导致事务 A 两次读到的数据可能是不一样的。这就发生了在一个事务内两次读到的数据不一样,这就被称作不可重复读。

解决办法:把数据库事务隔离级别调整到 REPEATABLE_READ。

  • 幻读
    指一个事务 A 对一个表中的数据进行了修改,而且该修改涉及到表中所有的数据行;同时另一个事务 B 也在修改表中的数据,该修改是向表中插入一行新数据。那么经过这一番操作之后,操作事务 A 的用户就会发现表中还有没修改的数据行,就像发生了幻觉一样。这就被称作幻读。

解决办法:把数据库事务隔离级别调整到 SERIALIZABLE_READ。

隔离级别

  • 读未提交(read uncommitted)
    一个事务还没提交时,它做的变更就能被别的事务看到。

  • 读提交(read committed)
    一个事务提交之后,它做的变更才能被别的事务看到。

  • 可重复读(repeatable read)
    一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复隔离级别下,未提交变更对其它事务也是不可见的。

  • 串行化(serializable)
    对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

自动提交

可以通过执行 set autocommit 1|0 来设置事务是否自动提交。
MySQL 默认为 1,表示开启自动提交。
如果没有开启自动提交,当前 session 所连接的 MySQL 的所有操作都会当成一个事务,直到输入 rollback/commit,当前事务才算结束。当前事务结束前新的 MySQL 连接时无法读取到任何 session 的操作的结果的。
如果开起了,mysql 会把每个sql语句当成一个事务然后自动的 commit。
当然无论开启与否,start transaction commit|rollback 都是独立的事务。

小礼物走一走,来 Github 关注我