浅谈MySQL事务隔离级别
mysql事务隔离一共有4个级别,分别是
读未提交(read uncommit)、读已提交(read commit)、可重复读(repeatable read)、可序列化(serializeble)
1. 读未提交(read uncommit)
读未提交是指事务1,读取到了事务2中修改的数据,且事务2还没有提交。
是最低级别的隔离,会导致脏读、不可重复读和幻读。
这张图中我们可以清晰的看到,事务2执行了修改操作将a修改成5,在事务2还未提交的时候,事务1再次查询a,结果a已经受影响了变成了5。
后果:这时如果事务2发送了异常执行了回滚操作,而事务1却还是一直在使用事务2修改后的数据进行操作,这时就发生脏读。
2. 读已提交(read commit)
读已提交指的是,事务2修改数据并提交了事务,这时事务1才会读取到事务2修改的数据。
读已提交可以避免脏读,但还是可能会导致不可重复读和幻读。
还是上一张图不过我们可以看到在事务2修改a的数据后,事务1的第二查询和第三次查询的区别。
后果:导致本事务发生不可重复读。
举例:比如事务1 执行了3条查询SQL分别是,查询总人数,查询男生人数,查询女生人数。实际上总人数是100,男生人数50,女生人数50。结果在执行过程中来了一条事务2将以为用户从男生修改为女生了。这样可能会导致事务1查询的结果出现:总人数100,男生50,女生51??
3. 可重复读(repeatable read)
可重复读指的,事务1的操作不受其它事务影响,在事务1中不管读取多少次都是重复一样的数据。
可重复读可以避免脏读和不可重复读,但还是可能发生幻读。
这也是MySQL的InnoDB引擎下默认的事务隔离级别,不可重复读通过mvcc实现。
后果:会出现幻读,在同一个事务中,之前查询没有的数据,在之后的查询中出现了。
注意 :这里值得一提是脏读和不可重复读主要是在一条数据中出现的,而幻读指的的是整个数据集。虽然他们比较相似,不过他们作用的区域差别是很大的。
4. 可序列化(serializeble)
这个隔离级别叫做串行,它也是最高的隔离级别最安全的。不过它的效率也是最低的,每次只能执行一个事务。