1、read uncommitted:读未提交
SQL1:select * from test where id = 1 SQL2:update test set name='newname' where id = 1
原理
操作一在进行数据库读操作时,不对数据库上任何锁;
操作二在进行更新操作时,对数据加行级共享锁。
现象:
事务1 | 事务2 |
select * from test where id = 1 |
|
update test set name='newname' where id = 1 |
|
select * from test where id = 1 |
|
rollback |
事务一共查询了两次,两次查询结果不一样。在两次查询的过程中,事务二对数据进行了修改,并未提交(commit)。但是事务一的第二次查询查到了事务二的修改结果。在数据库的读现象浅析中我们介绍过,这种现象我们称之为脏读。
2、read committed(读已提交)
原理
SQL1在读数据时加行级共享锁,读完该行立即释放;
SQL2在更新数据时加行级排他锁。只有在更新操作提交以后才允许其他操作,事务完成后释放
现象
SQL1进行两次读操作,在第一次读操作后,SQL2开始执行并对该数据加排他锁,SQL1只能等到SQL2执行完毕后执行第二次读操作。读已提交会导致两次读取的结果不一致,也就是不可重复读现象。
3、repeatable read(可重复读)
事务1:select * from test where age between 10 and 21;
事务2:insert into test values(1,'newname',20);
原理
SQL1进行读操作时,对操作数据加行级共享锁,直到事务结束才释放;
更新操作添加行级排他锁,更新后释放。
现象
只有事务一结束,事务2才可以执行,所以可以解决不可重复读的问题;
若是SQL2是插入语句,由于事务1对数据加的是行级共享锁,没有对整表加锁,所以SQL2可以执行。这样两次SQL1的结果不一致,导致幻读。
4、serializable(可序列化)
原理
读写都加表级排他锁