本文参考了这位博主的文章 ,大家可以去支持一下他
http://t.csdn.cn/GKnrP
下面我以更通俗,更简洁的话再来解释一遍
小知识:
读锁(共享锁):大家(多个线程,即多个用户)都可以读这个被读锁锁上的数据,但不能在对这个数据加写锁,可以加读锁。
写锁(排他锁/X锁):该锁一次只能被一个线程锁持有,只允许该线程写与读,不允许其他线程加任何锁进行读和写。
理解下面这段话很重要,不然你会对隔离性很懵逼。
首先给大家解释一下,一个事务不仅仅就一条语句哦! 所以才有读锁,写锁,串行化(也就是单独执行事务A。 B、C等待,)
下面是A、B、C三个事务。
MySQL事务的四大特征(ACID):
原子性(Atomicity)
就是 事务中的若干操作,要么全部执行,要么全部不执行.(如果某个步骤出现错误,就从这个步骤开始回滚回去rollback)
一致性(Consistency)
在事务执行操作前后,数据库的完整性不会因为这些操作而破坏,也就是说,事务执行前后,数据始终处于一种合法的状态.
例如: A本来只有1000 元,想要去转2000元给B,是不合法.
持久性(Durability)
事物一旦提交则不可逆,被持久化到数据库中。(即写入磁盘中)
隔离性(isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
事务四大特征之一————隔离性(isolation)
-
事物A和事物B之间具有一定的隔离性
-
隔离性有隔离级别(4个)
-
读未提交:read uncommitted
-
性能: 隔离性最低,并发性最高,存在脏读的问题。
出现的问题:允许读取未提交的数据。即事务A只执行了第一条的时候,事务B就读取。
通俗话讲:在别人写的时候读 (即脏读)。
注意:图片中的小明,两个步骤都是事务A
解决方法:对账户余额这个数据加写锁 。
2.读已提交:read committed
性能: 隔离性提高了,并发性降低了,存在不可重复读的的问题。
出现的问题:事务A在执行过程中,多次读取的数据不相同。
通俗话讲:在别人读的时候写 (即不可重复读)。
注意:图片中的小明执行的三个步骤都是事务A。而老师的两个步骤,分别是两次事务,不是同一个事务
解决方法:对小明成绩这个数据加读锁 。
3.可重复读: repeatable read
给读和写都加锁了,这是MySQL默认的隔离级别
性能: 隔离性又提高了,并发性更低了,存在幻读的的问题。
出现的问题:
事务A 有三个步骤:小明查看暑期作业有多少 -> 小明进行其他操作 -> 小明再次查看暑期作业有多少
事务B 老师添加暑期作业.
当事务A去执行的时候,第一次读操作,发现暑期作业只有10页.然后小明进行了其他的操作,此时事务B进行添加操作,又增加了90页.
当事务B再去查看的时候,发现作业页数变成了100页.
通俗话讲:事务A在执行第一步之后,由于第二步进行了其他操作,所以对于暑期作业页数这个数据的锁就解除了 ,导致老师可以对这个数据进行修改。 但是这个事务A还是没有执行完毕的。当事务A执行到第三步的时候,就发现数据已经被更改了。(即幻读)
解决方法:彻底让事务之间彻底的 串行化( serializable), 就是当事务A在执行的过程中,事务B什么也不能干,只能挂机等待.。
4. 串行化执行:serializable
隔离性最高,并发性最低,解决了幻读问题(所有问题).