LXX的网络日志
人因梦想而伟大
ACID以及几种隔离级别

ACID是什么?

ACID:
(1)Atomic:原子性,就是一堆SQL,要么都成功,要么都失败。一部分SQL成功了,一部分SQL失败了,就不是原子性了。

(2)Consitency:一致性,这个是针对数据的一致性来说,就是一组SQL执行之前,数据必须是准确的,执行之后,数据也必须是准确的。搞了半天,执行完SQL,结果SQL对应的数据修改没执行,那就不是一致性了。

(3)Isolation:隔离性,这个就是说多个事务在跑的时候不能相互干扰,事务A操作个数据,弄到一半还没弄完,结果事务B来改了这个数据,导致事务A的操作出错了。这个就没有隔离性了。

(4)Durability:持久性,事务成功了,对数据的修改应该是永久性的,不应该因为服务器重启、宕机了或者别的原因,导致数据丢失了,那这就不能算作是持久性。

事务的隔离级别

再说说隔离级别:
(1)读未提交,Read Uncommitted(脏读):简单的说,某个事务还没提交,但是修改了数据。结果被别的事务给读取到了,这个就是读未提交。但是它有脏读的情况,一台条数据一开始是1,事务A修改了值为2,但是还没提交,结果事务B就读到了,然后事务A因为某些原因把事务回滚了,结果事务Bzai再次读取,又变回1了。这个就是脏读。

(2)读已提交,Read Committed(不可重复读):简单的说,某个事务已经修改完数据了,事务也提交了,但是它的数据在别的事务一开始读的某个字段的值是1,结果下次读就变成2了。这个就是读以提交。

(3)可重复读,Read Repeatable:就是某条数据,一开始是1,事务A先修改了它,把它变成了2。事务B一开始读到的是1,事务A提交后,事务B读到的还是1。无论这条数据修改多少次,事务B在事务内读取到的这条数据始终都是1。

(4)串行化,Serializable:先了解一下幻读,不可重复读和可重复读都是针对两个事务同时对某条数据在修改,但是幻读针对的是插入,别的事务在查询条数的时候一开始是一条数据,后面再次查询,发现多出来一条,这个就是幻读。如果要解决幻读,就要使用串行化的隔离级别。所有的事务都会依次执行,不允许多个事务并行操作。因此,脏读、不可重复读、幻读都不会出现。

MySQL的事务隔离级别

MySQL的事务隔离级别默认是Read Repeatable,也就是可重复读。在MySQL的事务中,每次事务都会开启一个事务快照,在事务期间,读到的都是这个数据的快照,对一个数据多次读的结果都是一样的。

MySQL的可重复读是通过MVCC机制来实现的,多版本并发控制 multi-version concurrency control。

innodb存储引擎,会在每行的数据中,加两个隐藏列,一个保存行的创建时间,一个保存行的删除时间,但是存放的不是时间。而是事务ID,事务ID是MySQL自己维护。

在一个事务内查询的时候,MySQL指挥chacha下创建时间的事务ID小于等于当前的事务ID的行,这样可以确保这个行是在当前事务中创建,或者是之前创建的。

同时一个行的删除时间的事务ID要么没有定义(也就是没有删除),要么是比当前事务ID大(在事务开启之后才被删除);满足这两个条件的数据都会被查询出来。

如果某个事务执行期间,别的事务更新了一条数据。那么在innodb中,是插入了一行记录,然后将新插入的记录的创建时间设置为新的事务的ID,同时将这条记录之前的那个版本的删除时间设置为新的事务的ID。